【问题标题】:How to query a model made up of multiple Foreign Keys如何查询由多个外键组成的模型
【发布时间】:2019-12-28 21:45:18
【问题描述】:

我正在学习 CS50 Web 编程课程,学习使用 Django。学习练习基本上是让你用 django 重新创建this 比萨餐厅菜单。

我已经为数据创建了一些模型,现在我正在尝试使用 Django 模板为比萨创建一个菜单页面。

这是我的模型:

from django.db import models

class intToppings(models.Model):
    name = models.CharField(max_length=16)
    intToppings = models.IntegerField() # 0 Cheese, 1/2/3, 5 Special

    def __str__(self):
        return f"{self.name}"

class Size(models.Model):
    size = models.CharField(max_length=16)

    def __str__(self):
        return f"{self.size}"

class PizzaBase(models.Model):
    base = models.CharField(max_length=16)

    def __str__(self):
        return f"{self.base}"

class Toppings(models.Model):
    topping = models.CharField(max_length=32)

    def __str__(self):
        return f"{self.topping}"

class Pizza(models.Model):
    size = models.ForeignKey(Size, on_delete=models.CASCADE) # CASCADE will delete all Regular Pizzas if their size is deleted (as opposed to .SET_NULL)
    base = models.ForeignKey(PizzaBase, on_delete=models.CASCADE)
    intToppings = models.ForeignKey(intToppings, on_delete=models.CASCADE)
    price = models.IntegerField() # price in cents

    def __str__(self):
        return f"{self.size} {self.base} {self.intToppings} Pizza"

Size db 中有一个条目 "small""large",对于 intToppings,有一个名称为 "cheese" 和一个 int 为 0 的条目,另一个用于 "1 topping" 的 int 1 等。

对于Pizza 型号,我为菜单上的每个组合都做了一个条目,即:

<QuerySet [<Pizza: small Regular Cheese Pizza>, <Pizza: small Regular 1 Topping Pizza>, <Pizza: small Regular 2 Toppings Pizza>,  ...
... <Pizza: large Sicilian 2 Toppings Pizza>, <Pizza: large Sicilian 3 Toppings Pizza>, <Pizza: large Sicilian Special Pizza>]>

在我的views.py 上,我不能真正将整个数据集传递给django 模板,因为循环通过它来创建一个html 表是不明智/不可能的。 (我的 html 表与their website 上的相同,一张用于普通披萨,一张用于西西里。)

我试图通过首先构造一个列表/数组或字典对象来解决这个问题,这些对象将以易于循环的结构将数据传递给 django 模板。为此,我想查询Pizza 模型。

基本上,我要做的就是(伪代码:SELECT Pizza WHERE size="small" base="Regular", intToppings=0 并获取该披萨的价格。 不过,我似乎无法查询外键;

Pizza.objects.all().filter(price=1220)

有效,但不是我需要的。我需要的是;

p = Pizza.objects.all().filter(base="Regular", size="small", intToppings=0)
print(p.price)

这不起作用。

【问题讨论】:

  • 阅读this 了解跨越关系的查找。

标签: python django django-models django-templates


【解决方案1】:

您是否尝试过使用相关模型的字段名称?像这样:

p = Pizza.objects.filter(
    base__base="Regular",
    size__size="small",
    intToppings__intToppings=0)
print(p)

就像docs 说的那样, 您首先访问相关模型(例如base),然后访问该相关模型的字段(__base)并将其与您想要的字符串进行比较,得到base__base='something'

也许您甚至可以将字段 PizzaBase.base 重命名为 PizzaBase.name 以减少混乱。

【讨论】:

  • 谢谢!效果很好,除了我必须做的最后一个intToppings__intToppings=0。是的,我同意,使用这种语法,绝对最好将它们重命名为 name
【解决方案2】:

试试这个:

p = Pizza.objects.filter(
    base__base = "Regular",
    size__size = "small",
    intToppings_id = 0, 
)

注意,我将 intToppings 更改为 intToppings_id。如果需要外键过滤,可以传入intToppings对象,也可以在列名后面加上_id,直接插入pk值即可。

【讨论】:

    猜你喜欢
    • 2011-06-15
    • 1970-01-01
    • 2020-12-20
    • 2015-10-22
    • 1970-01-01
    • 2021-12-27
    • 2015-01-29
    • 1970-01-01
    相关资源
    最近更新 更多