【问题标题】:How to query many to many relationships on django?如何在 django 上查询多对多关系?
【发布时间】:2017-03-22 10:38:27
【问题描述】:

我正在为食物食谱编写应用程序。我希望它能够区分食谱以避免特定的食物不耐受(即乳糖、鸡蛋、麸质、SO2 ......)。为此,我提出了这个模型:

models.py

from django.db import models
from unittest.util import _MAX_LENGTH

class Alimento(models.Model):
    INTOLERANCIAS = (
        ('00', 'Ninguna'),
        ('GL', 'Gluten'),
        ('CR', 'Crustáceos'),
        ('HU', 'Huevos'),
        ('FS', 'Frutos Secos'),
        ('AP', 'Apio'),
        ('MO', 'Mostaza'),
        ('SE', 'Sésamo'),
        ('PE', 'Pescado'),
        ('CA', 'Cacahuetes'),
        ('SO', 'Sulfitos'),
        ('SJ', 'Soja'),
        ('LA', 'Lácteos'),
        ('AL', 'Altramuz'),
        ('ML', 'Moluscos'),
        ('CA', 'Cacao'),


    )
    nombre = models.CharField(max_length=60)
    intolerancia = models.CharField(max_length=2, choices=INTOLERANCIAS)

    def __str__(self):
        return self.nombre


class Receta(models.Model):
    nombre = models.CharField(max_length=100)
    raciones = models.IntegerField(default=1)
    preparacion = models.TextField(default='')
    consejos = models.TextField(blank=True)
    ingredientes = models.ManyToManyField(Alimento, through='Ingrediente')

    def __str__(self):
        return self.nombre


class Ingrediente(models.Model):
    receta = models.ForeignKey('recetas.Receta', on_delete=models.CASCADE)
    alimento = models.ForeignKey('recetas.Alimento', related_name='ingredientes', on_delete=models.CASCADE)
    cantidad = models.FloatField(default=0)
    descripcion = models.CharField(max_length=60, blank=True)

    def __str__(self):
        return self.alimento.__str__()

我已经在 admin.py 中注册了它们,我可以创建/更新/删除它们,但是我在管理 UI 的任何地方都看不到 manytomany 字段。

admin.py 从 django.contrib 导入管理员

from .models import Alimento, Receta, Ingrediente

admin.site.register(Alimento)
admin.site.register(Receta)
admin.site.register(Ingrediente)

所以我去 shell 并在那里尝试了一些查询

Alimento.objects.all()
<QuerySet [<Alimento: Pan>, <Alimento: Tomate>, <Alimento: Vinagre de vino>, <Alimento: Ajo>, <Alimento: Pimiento Verde>, <Alimento: Sal>, <Alimento: Aceite de Oliva>]>


Receta.objects.all()
<QuerySet [<Receta: Gazpacho>]>


gaz = Receta.objects.get(nombre='Gazpacho')
Ingrediente.objects.filter(receta=gaz)
<QuerySet [<Ingrediente: Pan>, <Ingrediente: Tomate>, <Ingrediente: Tomate>, <Ingrediente: Pimiento Verde>, <Ingrediente: Aceite de Oliva>, <Ingrediente: Vinagre de vino>, <Ingrediente: Ajo>]>

pan = Alimento.objects.get(nombre='Pan')
pan.intolerancia
'GL'

鉴于此,我如何查询给定不耐受/过敏 (Alimento:intolerancia) 的食谱 (Receta)?

【问题讨论】:

标签: django django-models


【解决方案1】:

直接解决

class IngredienteInline(admin.TabularInline):
    model = Ingrediente
    extra = 1

class AlimentoAdmin(admin.ModelAdmin):
    inlines = (IngredienteInline,)

class RecetaAdmin(admin.ModelAdmin):
    inlines = (IngredienteInline,)

那么,

admin.site.register(Alimento, AlimentoAdmin)
admin.site.register(Receta, RecetaAdmin)

参考doc

现在过滤器的查询是

Receta.objects.filter(ingredientes__intolerancia ='CR')

【讨论】:

    【解决方案2】:

    您可以使用您的模型 Receta 的字段 ingredientes 访问 Alimento 模型。在您的过滤器中,您可以使用它,并检查 intolerancia 的字段 Alimento

    Receta.objects.filter(ingredientes__intolerancia='GL')
    

    在评论中的问题后更新,see documention

    Receta.objects.filter(ingredientes__intolerancia_in=['GL', 'CR'])
    

    【讨论】:

    • 我试过了,它有效,谢谢!是否可以给它多个不容忍值?相当于 SQL "intolerancia in ('GL', SO', 'HU')" ?
    • 非常感谢! :D
    猜你喜欢
    • 2017-02-02
    • 1970-01-01
    • 2013-11-22
    • 2011-11-13
    • 2015-10-26
    • 1970-01-01
    • 2021-03-07
    • 2014-07-14
    相关资源
    最近更新 更多