首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在django中跨多个ForeignKey进行过滤?

如何在django中跨多个ForeignKey进行过滤?
EN

Stack Overflow用户
提问于 2014-03-19 20:58:43
回答 1查看 293关注 0票数 0

我的non_toxic_items()方法不返回‘正确’集。

目前,

代码语言:javascript
复制
Item.inventory.all() 

返回小于

代码语言:javascript
复制
Item.inventory.non_toxic_items()

这是我的经理,有问题的方法。请参阅函数中的说明,以了解我希望它返回的内容。

代码语言:javascript
复制
#manager.py
from django.db import models


class InventoryManager(models.Manager):

    def get_queryset(self):
        return super(InventoryManager, self).get_queryset().filter(
            shipment__isnull=True, )

    def non_toxic_items(self):
        """
        Return all non-toxic items, not part of a shipment.

        As python code::

    context['my_qs'] = []
    for batch in self.object_list:
        flag = False
        for input in batch.input_set.all():
            if input.material.type.is_toxic:
                flag=True
        if not flag:
            for item in batch.item_set.all():
                if item.shipment is None:
                    context['my_qs'].append(item)
        """
        return super(InventoryManager, self).get_queryset().filter(
            # BUG -- Does not return the same queryset as above python code.
            shipment__isnull=True,
            batch__input__material__type__is_toxic=False).distinct()

这些都是模型

代码语言:javascript
复制
from django.db import models
from .managers import InventoryManager
from shipment.models import Shipment


class MaterialType(models.Model):
    type = models.CharField(max_length=255, )
    is_toxic = models.BooleanField(default=False, )
    ...


class Material(models.Model):
    type = models.ForeignKey(MaterialType)
    lot_number = models.CharField(max_length=50, )
    ...


class Batch(models.Model):
    batch_number = models.IntegerField(primary_key=True, )
    ...


class Input(models.Model):
    """
    These are input materials to a batch.
    A batch may contain at most 1 toxic material.
    """
    batch = models.ForeignKey(Batch)
    material = models.ForeignKey(Material)
    ...


class Item(models.Model):
    id_number = models.IntegerField(primary_key=True, )
    batch = models.ForeignKey(Batch, )
    shipment = models.ForeignKey(Shipment, blank=True, null=True, )
    ...
    objects = models.Manager()
    inventory = InventoryManager()

我已经删除了与查询无关的所有字段。该方法有效,但输出不正确.(它与描述中的代码不匹配)

如果有人有比那个昂贵的加入更好的解决方案,我很想听听。

编辑:详细信息:

代码语言:javascript
复制
# imports go here

class BatchListView(generic.ListView):
    model = Batch
    paginate_by = 25

    def get_context_data(self, **kwargs):
        context = super(BatchListView, self).get_context_data(**kwargs)
        context['items_non_toxic'] = Item.inventory.non_toxic_items()
        context['my_qs'] = []
        for batch in self.object_list:
            flag = False
            for my_input in batch.input_set.all():
                if my_input.material.type.is_toxic:
                    flag=True
            if not flag:
                for my_item in batch.item_set.all():
                    if my_item.shipment is None:
                        context['my_qs'].append(my_item)
        return context

{{ my_qs }} #返回73项

、20、21、22、23、24、25、26、27、28、29、30、31、32、14035、14042、14043、14044、14045、14046、14047、14048、14049、14050、14051、14052、14053、14054、14055、14056、14057、14058、14059,14060、14061、14062、14063、14064、14065、14066、14067、14068、14069、14070、14071、14072、14073、14074、14075、14076、14077、14078、14079、14080、14081、14082、14083、14084、14085、14086、14087、14088、14089、14090、14091、14092,14093 14094 14095 14096 14097 14098 14099 14100

{{ items_non_toxic }} #返回115个项

4、5、6、7、8、9、10、11、20、21、22、23、24、25、26、27、28、29、30、31、32、10000、10001、10002、10003、10004、10005、10006、10007、10008、10009、10010、10011、10012、10013、10014、10015、10016、10017、10018、10019、10020、10021、10022、10023、14035、14042、14043、14044、14045、14046、14047、14048、14049、14050、14051、14052、14053、14054、14055、14056、14057、14058、14059、14060、14061,14062、14063、14064、14065、14066、14067、14068、14069、14070、14071、14072、14073、14074、14075、14076、14077、14078、14079、14080、14081、14082、14083、14084、14085、14086、14087、14088、14089、14090、14091、14092、14093、14094,14095,14096,14097,14098,14099,14100,45361,45362,45363,45364,45365,45366,45367,45368,45369,45370,

EN

回答 1

Stack Overflow用户

发布于 2014-03-20 14:44:33

这个解决方案来自于双沼泽:

multiple/cg7db8l

代码语言:javascript
复制
def non_toxic_items(self):
    return super(InventoryManager, self).get_queryset().filter(
        shipment__isnull=True,
        ).exclude(batch__in=Batch.objects.filter(
                input__material__type__is_toxic=True))

https://docs.djangoproject.com/en/1.6/ref/models/querysets/#in描述了任何感兴趣的人在幕后发生的事情。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22517947

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档