综述
Django
ManyToManyField
的ORM
操作和在admin
中显示。
表结构设计
假设一个作者有多本书,一本书也可以有个作者,多对多关系。
# 表结构设计
class Book(models.Model):
title = models.CharField(max_length=20)
class Author(models.Model):
name = models.CharField(max_length=20)
books = models.ManyToManyField(Book)
在admin中显示
当数据过多时,django
自带的ManyToManyField
及其不方便。仅需在admin.py
添加如下字段即可。
# 修改前
admin.site.register(Author)
使用filter_horizontal
。在作多项选择的操作方便性,及单项选择太多时,会有极好的体验。
# 修改后
class AuthorAdmin(admin.ModelAdmin):
list_display = ['name'] # 列表页展示的字段
filter_horizontal = ('cards',)
admin.site.register(AuthorAdmin)
若想在admin中显示cards字段。增加如下代码即可
class AuthorAdmin(admin.ModelAdmin):
list_display = ['name','relatedbooks'] # 列表页展示的字段
def relatedbooks(self, obj):
return [book.title for book in obj.books.all()]
filter_horizontal = ('books',)
admin.site.register(Author,AuthorAdmin)
ORM操作
all 关联的所有的元组
一个作者的所有书。表Author中某一元组关联表Book中的所有元组
author = models.Author.objects.get(pk=1)
books = author.books.all()’
for book in books:
print(books.title)
add 添加多对多关系
重复添加同一关系django
会自动忽略
author = models.Author.objects.get(pk=1)
author.books.add(Book.objects.all())
author.books.add(Book.objects.get(id=3))
remove 多对多关系
author = models.Author.objects.get(pk=1)
author.books.remove(Book.objects.get(id=3))
set 替换
直接完整的替换某一多对多关系
author = models.Author.objects.get(pk=1)
author.books.set(Book.objects.get(id=3))
clear 清除
清除一元组所有多对多关系
author = models.Author.objects.get(pk=1)
author.books.clear()
一张表自关联
from django.db import models
class Person(models.Model):
friends = models.ManyToManyField("self")
当django处理这个模型时,它会做如此定义:对多对多字段关系被认为是对称的——即,如果我是你的朋友,那么你也是我的朋友。(跟)C++
一比,我是你的友元,你不是我的友元
然而有时候我们不需要这个友好关系,修改symmetrical
为False
即可。
symmetrical=Flase