我知道Django无法实现filtering by property,因为过滤是在数据库级别完成的,属性存在于Python代码中。但是,我有以下情况:
另一方面,我的模型RegisteredUser
另一方面Subscription
。用户可以有多个订阅,订阅来自一个用户,而用户有一个或没有活动订阅。
为了实现这一点,我有一个从Subscription
到RegisteredUser
的外键和一个subscription
的{{1}}指向活动的外键(最新创建的订阅)用户)或者如果他没有任何订阅则没有。
哪种方式可以过滤最有效的订阅“白金”,“黄金”,“白银”......的用户?我可以执行“获取所有订阅”,然后迭代它们以检查每个订阅是否匹配。但它真的很贵,如果我必须为每种订阅类型做同样的过程,那么成本就是s * u(其中RegisteredUser
是不同订阅的数量,而s
是用户数量。)
任何帮助将不胜感激。提前谢谢!
更新
当我第一次解释这个问题时,我没有包含所有与之相关的模型 简化小事。但是当你问我模型时,有些人还没有理解我 (也许我不够清楚)在这里你有代码。 我已经简化了模型并删除了现在不重要的代码。
我在这里有什么? u
可以有多个订阅(因为他可能会更改它)
他想要多次,订阅只来自一个用户。用户只有
一个当前订阅,这是最新的订阅,由酒店返回
RegisteredUser
。 subscription
附有Subscription
,这是其模型
Membership
可以是:铂金,黄金,白银等。
我需要什么?我需要查找slug
具有特定类型成员资格的Content
。
如果房产方法有效,我会这样做:
author
但我不能这样做,因为过滤时无法使用属性!
我认为我可以解决转换由此创建的“虚拟”关系的问题 将该属性转换为真正的ForeignKey,但这可能会导致副作用,因为我应该在每次用户更改其订阅时手动更新它,现在它是自动的!有更好的想法吗?
非常感谢!
Content.objects.filter(author__id__in=RegisteredUser.objects.filter(
subscription__membership__slug="gold"))
答案 0 :(得分:1)
最后,为了解决这个问题,我用一个真正的外键替换了subscription
属性,并添加了一个信号,用RegisteredUser
附加了创建的订阅。
外键:
subscription = models.ForeignKey(Subscription, verbose_name=_("Subscription"),
related_name='subscriber_set', blank=True, null=True)
信号:
@receiver(post_save, sender=Subscription)
def signal_subscription_post_save(sender, instance, created, **kwargs):
if created:
instance.subscriber.subscription = instance
instance.subscriber.save()
答案 1 :(得分:0)
我认为你的模特是这样的:
KIND = (("p", "platinum"), ("g","gold"), ("s","silver"),)
class RegisteredUser(models.Model):
# Fields....
class Subscription(models.Model):
kind = models.CharField(choices=KIND, max_len=2)
user = models.ForeignKey(RegisteredUser, related_name="subscriptions")
现在,您可以这样做:
gold_users = RegisteredUser.objects.filter(subscriptions_kind="g")
silver_users = RegisteredUser.objects.filter(subscriptions_kind="s")
platinum_users = RegisteredUser.objects.filter(subscriptions_kind="p")
使其适应您的模型
希望帮助
修改强>
Now, With your models, I think you want something like:
content_of_golden_users = Content.objects.filter(author__subscriptions_set__membership__slug="golden")
content_of_silver_users = Content.objects.filter(author__subscriptions_set__membership__slug="silver")
content_of_platinum_users = Content.objects.filter(author__subscriptions_set__membership__slug="platinum")