[英]Django ManyToMany relationship
在models.py 中:
from django.db import models
from django.utils.translation import ugettext as _
# Create your models here.
class Category(models.Model):
name = models.CharField(_(u"Name"), max_length=250)
products = models.ManyToManyField("Product", verbose_name=_(u"Products"), \
blank=True, null=True, related_name="+")
class Product(models.Model):
name = models.CharField(_(u"Name"), max_length=250)
category = models.ManyToManyField("Category", verbose_name=_(u"Category"), \
blank=True, null=True, related_name="+")
在管理页面:
问题:
如何设置models.py中products
和category
m2m 字段之间的关系,以便在管理页面中,如图所示, b2
(产品)被标记为属于a2
(类别)。
欢迎就 [产品、类别] 的实施提出任何建议,谢谢。
聚苯乙烯
我是 Django 的新手。对不起我的英语。
问题是你有两个 ManyToMany字段。 正如您所指出的那样,当关系设置在其中一个中时,它就不在另一个中。
解决方案很简单:删除其中一个字段。 您只需要在关系的一侧使用ManyToManyField。 Django让您自动访问另一方。 因此,如果您在Product
型号上保留了categories
字段,则可以执行my_product.categories.all()
以获取与产品相关联的类别; 和my_category.product_set.all()
获取属于某个类别的产品。
你还需要删除related_name="+"
属性:你可能会把它放进去因为你遇到了冲突,这应该是一个线索。
在Django中有两种创建“多对多”关系的方法。 一个不使用“ManyToManyField()” ,一个使用“ManyToManyField()” 。 首先,我将向您展示不使用"ManyToManyField()"的方法。
要创建多对多关系,必须有2 个其他表之间的中间表,并且它必须具有来自 2 个其他表的每个外键,并且这些外键必须是唯一的。 因此,我在“Category”和“Product”表之间创建了中间表“CategoryProduct” ,它具有来自“Category”和“Product”表的每个外键,这些外键是唯一的,如下所示。
“模型.py” :
from django.db import models
class Category(models.Model):
name = models.CharField(max_length=255)
def __str__(self):
return self.name
class Product(models.Model):
name = models.CharField(max_length=255)
def __str__(self):
return self.name
# The middle table between "Category" and "Product" tables
class CategoryProduct(models.Model):
category = models.ForeignKey(Category, on_delete=models.CASCADE)
product = models.ForeignKey(Product, on_delete=models.CASCADE)
class Meta:
unique_together = [['category', 'product']]
这就是将中间表“CategoryProduct”内联到“Product”表的方式,如下所示。
“管理员.py” :
from django.contrib import admin
from .models import CategoryProduct, Product
class CategoryProductInline(admin.TabularInline):
model = CategoryProduct
min_num = 1
extra = 2
max_num = 5
@admin.register(Product)
class ProductAdmin(admin.ModelAdmin):
inlines = [CategoryProductInline]
这是它的样子:
这就是将中间表“CategoryProduct”内联到“Category”表的方式,如下所示。
“管理员.py” :
from django.contrib import admin
from .models import CategoryProduct, Category
class CategoryProductInline(admin.TabularInline):
model = CategoryProduct
min_num = 1 # 1 required inline field displayed
extra = 2 # 2 unrequired inline fields displayed
max_num = 5 # 5 inline fields as a maximum
@admin.register(Category)
class CategoryAdmin(admin.ModelAdmin):
inlines = [CategoryProductInline]
这是它的样子:
这是“ManyToManyField()”的方法,如下所示。 上面使用“ManyToManyField()”的方式和没有使用“ ManyToManyField()”的方式之间的区别是在这种情况下使用“ManyToManyField()”的方式,带有“ ManyToManyField()”的“类别”字段被添加到“产品” “ class正如您在下面看到的,它们之间唯一的代码不同,所以其他都是一样的。
“模型.py” :
from django.db import models
class Category(models.Model):
name = models.CharField(max_length=255)
def __str__(self):
return self.name
class Product(models.Model):
name = models.CharField(max_length=255)
categories = models.ManyToManyField(
Category,
through='CategoryProduct'
) # "categories" field is added
def __str__(self):
return self.name
class CategoryProduct(models.Model):
category = models.ForeignKey(Category, on_delete=models.CASCADE)
product = models.ForeignKey(Product, on_delete=models.CASCADE)
class Meta:
unique_together = [['category', 'product']]
您可以将带有“ManyToManyField()”的“产品”字段添加到“类别”class ,并且只有代码不同,所以其他内容也相同。
“模型.py” :
from django.db import models
class Product(models.Model):
name = models.CharField(max_length=255)
def __str__(self):
return self.name
class Category(models.Model):
name = models.CharField(max_length=255)
products = models.ManyToManyField(
Product,
through='CategoryProduct'
) # "products" field is added
def __str__(self):
return self.name
class CategoryProduct(models.Model):
category = models.ForeignKey(Category, on_delete=models.CASCADE)
product = models.ForeignKey(Product, on_delete=models.CASCADE)
class Meta:
unique_together = [['category', 'product']]
因此,将中间表“CategoryProduct”内联到“Product”表的方式也与没有“ManyToManyField()”的方式相同,如下所示。
“管理员.py” :
from django.contrib import admin
from .models import CategoryProduct, Product
class CategoryProductInline(admin.TabularInline):
model = CategoryProduct
min_num = 1
extra = 2
max_num = 5
@admin.register(Product)
class ProductAdmin(admin.ModelAdmin):
inlines = [CategoryProductInline]
这是它的样子:
并且,将中间表“CategoryProduct”内联到“Category”表的方式与没有“ManyToManyField()”的方式相同,如下所示。
“管理员.py” :
from django.contrib import admin
from .models import CategoryProduct, Category
class CategoryProductInline(admin.TabularInline):
model = CategoryProduct
min_num = 1 # 1 required inline field displayed
extra = 2 # 2 unrequired inline fields displayed
max_num = 5 # 5 inline fields as a maximum
@admin.register(Category)
class CategoryAdmin(admin.ModelAdmin):
inlines = [CategoryProductInline]
这是它的样子:
此外,当您使用“ManyToManyField()”时,您可以删除可自定义的中间表“CategoryProduct”的代码。 在这种情况下,您删除中间表“CategoryProduct”的代码,隐式创建不可自定义的默认中间表。 因此,我从“ManyToManyField()”中删除了中间表“CategoryProduct”和“through='CategoryProduct'”的代码,如下所示。
“模型.py” :
from django.db import models
class Category(models.Model):
name = models.CharField(max_length=255)
def __str__(self):
return self.name
class Product(models.Model):
name = models.CharField(max_length=255)
categories = models.ManyToManyField(Category)
categories = models.ManyToManyField(
Category,
# through='CategoryProduct'
)
def __str__(self):
return self.name
# class CategoryProduct(models.Model):
# category = models.ForeignKey(Category, on_delete=models.CASCADE)
# product = models.ForeignKey(Product, on_delete=models.CASCADE)
# class Meta:
# unique_together = [['category', 'product']]
并且只需如下所示注册“Product” ,您就可以使用默认中间表的内联创建“Product”表的形式。
“管理员.py” :
from django.contrib import admin
from .models import Product
admin.site.register(Product)
这就是它的样子。 如您所见, “类别”的 UI(用户界面)与具有自定义中间表“CategoryProduct”时不同。 对我来说,拥有自定义中间表“CategoryProduct”时的 UI 更好:
即使您注册“类别”表,如下所示。
“管理员.py” :
from django.contrib import admin
from .models import Category
admin.site.register(Category)
默认中间表未内联到“类别”表,如下所示:
要将默认中间表内联到“类别”表, “类别”表必须具有如下所示的ManyToManyField() 。
“模型.py” :
from django.db import models
class Product(models.Model):
name = models.CharField(max_length=255)
def __str__(self):
return self.name
class Category(models.Model):
name = models.CharField(max_length=255)
products = models.ManyToManyField( # Here
Product,
# through='CategoryProduct'
)
def __str__(self):
return self.name
# class CategoryProduct(models.Model):
# category = models.ForeignKey(Category, on_delete=models.CASCADE)
# product = models.ForeignKey(Product, on_delete=models.CASCADE)
# class Meta:
# unique_together = [['category', 'product']]
然后,只需如下所示注册“Category” ,就可以使用默认中间表的内联创建“Category”表的形式。
“管理员.py” :
from django.contrib import admin
from .models import Category
admin.site.register(Category)
这是它的样子:
这就是您在Django中创建“多对多”关系的方式。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.