我正在学习django,并且我正在做一个制作比萨订购门户的项目。
我决定分别制作浇头和比萨饼的模型,以便以后可以添加更多的浇头,并为其中的比萨饼选择模型,但是我似乎无法弄清楚应该用于链接这两者的关系模式
我偶然发现了外键方法,但这不是我想要的 这是模型代码的一部分:
class Topping(models.Model):
name = models.CharField(max_length = 30)
def __str__(self):
return self.name
class Pizza(models.Model):
name = models.CharField(max_length=40)
first_toppping = models.Topping()
second_topping = models.Topping()
# in inches
size = models.IntegerField(max_length=3)
price = models.FloatField()
请提出一种链接这两者的方法。
答案 0 :(得分:2)
如果我很了解您,每个比萨饼都有很多浇头,所以您必须使用很多。这样,您可以添加任意数量的浇头(0-*)
class Topping(models.Model):
name = models.CharField(max_length = 30, unique = True)
def __str__(self):
return self.name
class Pizza(models.Model):
name = models.CharField(max_length=40)
toppings = models.ManyToManyField(Topping)
# in inches
size = models.IntegerField(max_length=3)
price = models.FloatField()
如以下示例所示,我创建了一个披萨对象,并添加了所需的浇头:
pizza = Pizza(name="CheesePizza",size=5,price=25.22)
pizza.save()
topping1 = Topping(name="chocolate")
topping1.save()
topping2 = Topping(name="whataver")
topping2.save()
topping3 = Topping(name="component")
topping3.save()
pizza.toppings.add(topping1,topping2,topping3)
答案 1 :(得分:1)
鉴于Pizza
有两个Topping
,则应在ForeignKey
上添加两个Topping
:
from django.utils.translation import gettext_lazy as _
class Topping(models.Model):
# ...
pass
class Pizza(models.Model):
name = models.CharField(max_length=40)
first_toppping = models.ForeignKey(
Topping,
on_delete=models.DO_NOTHING,
related_name='pizza_first'
)
second_topping = models.ForeignKey(
Topping,
on_delete=models.DO_NOTHING,
related_name='pizza_second'
)
size = models.IntegerField(max_length=3)
price = models.FloatField()
def clean(self):
# given we want the two toppings to be different
if self.first_topping_id == self.second_topping_id:
raise ValidationError(_('Toppings should be different.'))
return super(Pizza, self).clean()
或者您可以使ForeignKey
可以为空,这样,如果其中一个浇头是NULL
,则这意味着我们不选择第一/第二浇头:
from django.utils.translation import gettext_lazy as _
class Topping(models.Model):
# ...
pass
class Pizza(models.Model):
name = models.CharField(max_length=40)
first_toppping = models.ForeignKey(
Topping,
on_delete=models.SET_NULL,
null=True,
related_name='pizza_first'
)
second_topping = models.ForeignKey(
Topping,
on_delete=models.SET_NULL,
null=True,
related_name='pizza_second'
)
size = models.IntegerField(max_length=3)
price = models.FloatField()
def clean(self):
# given we want the two toppings to be different
if self.first_topping_id is not None and self.second_topping_id is not None and self.first_topping_id == self.second_topping_id:
raise ValidationError(_('Toppings should be different.'))
return super(Pizza, self).clean()
因此,我们在此建模比萨饼两次链接到浇头。
根据应用程序,您可能希望允许用户选择任意数量的浇头,有时甚至可以多次选择相同浇头。
为此,我们可以使用ManyToManyField
[Django-doc],并且如果我们希望能够将相同的顶部添加两次(或更多),则可以使用through
表,例如:
# a pizza can have the same topping multiple times
class Topping(models.Model):
# ...
pass
class PizzaTopping(models.Model):
pizza = models.ForeignKey('Pizza')
topping = models.ForeignKey(Topping)
class Pizza(models.Model):
name = models.CharField(max_length=40)
toppping = models.ManyToManyField(
Topping,
through=PizzaTopping,
related_name='pizzas'
)
size = models.IntegerField(max_length=3)
price = models.FloatField()