Django - ManyToMany 我可以多次 select 同一个外国模型
Django - ManyToMany where I could select the same foreign model multiple times
很抱歉,如果有人回答了这个问题,我不确定如何表达,所以找不到现有的解决方案。
假设我有一个基本的多对多关系,如下所示:
class Topping(models.Model):
name = models.Charfield()
class Pizza(models.Model):
toppings = models.ManyToMany(Topping)
这很简单也很棒,但是在我正在进行的项目中,我希望能够 select 多次使用相同的 Topping。例如,["pepperoni", "mushroom", "onion"] 将是一个非常好的结果,但我需要允许类似 ["pepperoni", "pepperoni", "pepperoni"]
我试过使用中间值 class,其中 Pizza 有一个 ManyToMany 到 Topping,它只是 ToppingType 的外键,即 Charfield -
class ToppingType(models.Model):
name = models.Charfield()
class Topping(models.Model):
type = models.ForeignKey(ToppingType)
class Pizza(models.Model):
toppings = models.ManyToMany(Topping)
这行得通,但是这意味着如果有一天我用五个“意大利辣香肠”select离子创造了一些东西,那么我的数据库中就会永久拥有五个意大利辣香肠的副本作为浇头。
正如我在顶部提到的,我确信有一个相当干净的解决方案,但我在弄清楚如何用我的搜索措辞时遇到了麻烦。
你不需要 ManyToManyField
到 Topping
,你可以让 Topping
充当 junction table [wiki] and thus specify this as through=…
model [Django-doc]:
class ToppingType(models.Model):
name = models.Charfield(max_length=255, unique=True)
class Pizza(models.Model):
toppings = models.ManyToMany(
ToppingType,
<b>through='Topping'</b>
)
class Topping(models.Model):
type = models.ForeignKey(ToppingType, on_delete=models.CASCADE)
pizza = models.ForeignKey(Pizza, on_delete=models.CASCADE)
因此,您在此处为每个 pizza
每个浇头创建一个 Topping
对象。但是您不要复制 ToppingType
s。事实上,如果你没有指定 through=…
,那么 Django 会创建一个(隐藏的)模型作为连接模型。
因此,您可以创建例如 ToppingType
s 意大利辣香肠和洋葱:
pepperoni = ToppingType.objects.create(name='pepperoni')
onion = ToppingType.objects.create(name='onion')
然后对于披萨添加 pepperoni
、onion
和 pepperoni
:
my_pizza = Pizza.objects.create()
Topping.objects.create(<b>pizza=my_pizza, type=pepperoni</b>)
Topping.objects.create(<b>pizza=my_pizza, type=onion</b>)
Topping.objects.create(<b>pizza=my_pizza, type=pepperoni</b>)
很抱歉,如果有人回答了这个问题,我不确定如何表达,所以找不到现有的解决方案。
假设我有一个基本的多对多关系,如下所示:
class Topping(models.Model):
name = models.Charfield()
class Pizza(models.Model):
toppings = models.ManyToMany(Topping)
这很简单也很棒,但是在我正在进行的项目中,我希望能够 select 多次使用相同的 Topping。例如,["pepperoni", "mushroom", "onion"] 将是一个非常好的结果,但我需要允许类似 ["pepperoni", "pepperoni", "pepperoni"]
我试过使用中间值 class,其中 Pizza 有一个 ManyToMany 到 Topping,它只是 ToppingType 的外键,即 Charfield -
class ToppingType(models.Model):
name = models.Charfield()
class Topping(models.Model):
type = models.ForeignKey(ToppingType)
class Pizza(models.Model):
toppings = models.ManyToMany(Topping)
这行得通,但是这意味着如果有一天我用五个“意大利辣香肠”select离子创造了一些东西,那么我的数据库中就会永久拥有五个意大利辣香肠的副本作为浇头。
正如我在顶部提到的,我确信有一个相当干净的解决方案,但我在弄清楚如何用我的搜索措辞时遇到了麻烦。
你不需要 ManyToManyField
到 Topping
,你可以让 Topping
充当 junction table [wiki] and thus specify this as through=…
model [Django-doc]:
class ToppingType(models.Model):
name = models.Charfield(max_length=255, unique=True)
class Pizza(models.Model):
toppings = models.ManyToMany(
ToppingType,
<b>through='Topping'</b>
)
class Topping(models.Model):
type = models.ForeignKey(ToppingType, on_delete=models.CASCADE)
pizza = models.ForeignKey(Pizza, on_delete=models.CASCADE)
因此,您在此处为每个 pizza
每个浇头创建一个 Topping
对象。但是您不要复制 ToppingType
s。事实上,如果你没有指定 through=…
,那么 Django 会创建一个(隐藏的)模型作为连接模型。
因此,您可以创建例如 ToppingType
s 意大利辣香肠和洋葱:
pepperoni = ToppingType.objects.create(name='pepperoni')
onion = ToppingType.objects.create(name='onion')
然后对于披萨添加 pepperoni
、onion
和 pepperoni
:
my_pizza = Pizza.objects.create()
Topping.objects.create(<b>pizza=my_pizza, type=pepperoni</b>)
Topping.objects.create(<b>pizza=my_pizza, type=onion</b>)
Topping.objects.create(<b>pizza=my_pizza, type=pepperoni</b>)