[英]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.