我有以下型号:
class Deal(models.Model):
date = models.DateTimeField(auto_now_add=True)
retailer = models.ForeignKey(Retailer, related_name='deals')
description = models.CharField(max_length=255)
...etc
class CustomerProfile(models.Model):
saved_deals = models.ManyToManyField(Deal, related_name='saved_by_customers', null=True, blank=True)
dismissed_deals = models.ManyToManyField(Deal, related_name='dismissed_by_customers', null=True, blank=True)
我想要做的是为客户检索交易,但我不想包含他们已经解雇的交易。
我在围绕多对多关系时遇到困难,并且没有运气弄清楚如何进行此查询。我假设我应该在Deal.objects()上使用排除,但我看到的排除的所有示例都排除了一个项目,而不是多个项目。
当我天真地尝试时:
deals = Deal.objects.exclude(customer.saved_deals).all()
我收到错误:"' ManyRelatedManager'对象不可迭代"
如果我说:
deals = Deal.objects.exclude(customer.saved_deals.all())。all()
我得到了#34;太多的值要打开" (虽然我觉得我应该注意到目前数据库中只有5个交易和2个客户)
我们(我们的客户)假设他/她将来会有成千上万的客户和成千上万的交易,所以我希望尽我所能保持绩效。如果此设置不正确,我很想知道更好的方法。
此外,我正在运行django 1.5,因为它部署在App Engine上(使用CloudSQL)
我哪里错了?
答案 0 :(得分:2)
建议您使用customer.saved_deals获取要排除的交易ID列表(使用values_list快速转换为平面列表)。
这可以保存您在联接表中的字段排除。
deals = Deals.exclude( id__in=customer.saved_deals.values_list('id', flat=True) )
答案 1 :(得分:0)
您想要更改此内容:
Twilio.Device.setup()
对于这样的事情:
deals = Deal.objects.exclude(customer.saved_deals).all()
基本上,deals = Deal.objects.exclude(customer__id__in=[1,2,etc..]).all()
是customer
外键,因此您无法直接使用many-to-many
。
答案 2 :(得分:0)
已保存的交易和被解雇的交易是描述几乎相同的两个字段。如果允许这两个字段存储Null值,则在数据库中也可能存在太多列的风险。值得考虑删除dismissed_deals,并将saved_deal仅用于True或False语句。
要考虑的另一件事是将saved_deals从CustomerProfile类移到Deals类。 Saved_deals是关于交易的,所以它更喜欢住在Deals类。
class Deal(models.Model):
saved = models.BooleanField()
customer = models.ForeignKey(CustomerProfile)
....
真正的交易本来是由一个客户/买家而不是少数。真正的客户可以拥有数百万的交易,因此与客户达成交易将是一个好方法。
deals_for_customer = Deals.objects.all().filter(customer__name = "John")
我想要做的是为客户检索交易,但我不想包含他们已经解雇的交易。
deals_saved = deals_for_customer.filter(saved = True)
客户和名称(customer__name)之间有双重下划线,它允许过滤model_name(客户与模型名称CustomerProfile相关)和该模型中的字段名称(假设CutomerProfile类具有名称属性)
{{1}}
就是这样。我希望我能帮忙。如果没有,请告诉我。