'ManyToManyField'查询

时间:2017-03-22 16:32:45

标签: django django-models

我正在推进web app I asked about earlier

目前,我的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', related_name='ingredientes')

    def __str__(self):
        return self.nombre

    def getIntolerancias(self):
        ing = self.ingredientes.all()
        intolerancias = []
        for i in ing:
            alimentos = i.alimento.all()
            for a in alimentos:
                intolerancias.append(a.get_intolerancia_display()) 

        return intolerancias



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

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

方法getIntolerancias应该列出与给定食谱(Receta)的每种成分相关的食物不耐受性。为此,我尝试使用ing = self.ingredientes获取成分的查询集(Ingrediente),但是当我在shell上尝试它时,我收到此错误消息

Traceback (most recent call last):   File "/usr/lib/python3.5/code.py", line 91, in runcode
    exec(code, self.locals)   File "<console>", line 1, in <module>   File "/usr/local/lib/python3.5/dist-packages/django/db/models/fields/related_descriptors.py", line 476, in __get__
    return self.related_manager_cls(instance)   File "/usr/local/lib/python3.5/dist-packages/django/db/models/fields/related_descriptors.py", line 758, in __init__
    self.target_field_name = rel.field.m2m_reverse_field_name()   File "/usr/local/lib/python3.5/dist-packages/django/utils/functional.py", line 15, in _curried
    return _curried_func(*(args + moreargs), **dict(kwargs, **morekwargs))   File "/usr/local/lib/python3.5/dist-packages/django/db/models/fields/related.py", line 1504, in _get_m2m_reverse_attr
    return getattr(self, cache_attr) AttributeError: 'ManyToManyField' object has no attribute '_m2m_reverse_name_cache'

我已经搜索过该错误,但是the answers I've found似乎没有我需要的东西(我可能只是不明白它看到了吗?)

更新

当我在shell上运行时,我会这样做

g = Receta.objects.get(nombre = 'Gazpacho')
g.getIntolerancias()

我收到错误

  

intolerancias.append(a.get_intolerancia_display())AttributeError:   'Ingrediente'对象没有属性'get_intolerancia_display'

但是,如果我迭代并获取g.ingredientes.all()的第一个元素并调用get_intolerancia_display()它确实可以正常工作

a = g.ingredientes.all().first()
a.get_intolerancia_display()
'Gluten'

1 个答案:

答案 0 :(得分:1)

评论后更新:

Documentation about Many-to-many relation

def get_intolerancias(self):
        alimentos = self.ingredientes.all() # Give us all alimento of a recetta
        intolerancias = []
        for a in alimentos:
            intolerancias.append(a.get_intolerancia_display())            
        return intolerancias