フィルタリングはデータベース レベルで行われ、プロパティは Python コードに存在するため、Django ではプロパティによるフィルタリングができないことを私は知っています。ただし、次のシナリオがあります。
片手には模型RegisteredUser
を、もう片方には模型を持っていSubscription
ます。ユーザーは複数のサブスクリプションを持つことができます。サブスクリプションは 1 人のユーザーからのものであり、ユーザーはアクティブなサブスクリプションを 1 つ持っているか、まったく持っていません。
これを実装するために、からの外部キーSubscription
とRegisteredUser
、そのプロパティsubscription
がRegisteredUser
アクティブなもの (そのユーザーに対して最後に作成されたサブスクリプション) を指すか、サブスクリプションがない場合は何もありません。
サブスクリプションが「プラチナ」、「ゴールド」、「シルバー」のユーザーをフィルタリングする最も効率的な方法はどれですか? 「すべてのサブスクリプションをフェッチ」してから、それらを繰り返し処理して、それぞれが一致するかどうかを確認できます。しかし、それは非常に高価であり、サブスクリプションの種類ごとに同じプロセスを実行する必要がある場合、コストは s * u (s
は異なるサブスクリプションu
の数、 はユーザーの数) になります。
どんな助けでも大歓迎です。前もって感謝します!
アップデート:
最初に問題を説明したとき、少し単純化に関連するすべてのモデルを含めませんでした。しかし、あなたは私にモデルを求めていますが、あなたの何人かは私を理解していません (おそらく私は十分に明確ではありませんでした)。ここにコードがあります。モデルを単純化し、現在重要ではないコードを取り除きました。
私はここに何を持っていますか?ARegisteredUser
は多くのサブスクリプションを持つことができ (彼は何度でも変更できるため)、サブスクリプションは 1 人のユーザーからのものです。ユーザーが現在持っているサブスクリプションは 1 つだけです。これは最新のサブスクリプションであり、プロパティによって返されます
subscription
。Subscription
が付属しており、プラチナ、ゴールド、シルバー等のバリエーションが可能なMembership
モデルです
。slug
私が必要なものは何?特定の種類のメンバーシップを持つユーザーを検索する必要がありますContent
。author
プロパティ アプローチが機能する場合は、次のようにします。
Content.objects.filter(author__id__in=RegisteredUser.objects.filter(
subscription__membership__slug="gold"))
しかし、フィルタリング時にプロパティを使用できないため、これはできません。
プロパティによって作成された「仮想」関係を実際の ForeignKey に変換する問題を解決できると考えましたが、ユーザーがサブスクリプションを変更するたびに手動で更新する必要があるため、これは副作用を引き起こす可能性があり、現在は自動です! より良いアイデアはありますか?
本当にありがとう!
class RegisteredUser(AbstractUser):
birthdate = models.DateField(_("Birthdate"), blank=True, null=True)
phone_number = models.CharField(_("Phone number"), max_length=9, blank=True, default="")
@property
def subscription(self):
try:
return self.subscriptions_set.filter(active=True).order_by("-date_joined",
"-created")[0]
except IndexError:
return None
class Subscription(models.Model):
date_joined = models.DateField(_("Date joined"), default=timezone.now)
date_canceled = models.DateField(_("Date canceled"), blank=True, null=True)
subscriber = models.ForeignKey(AUTH_USER_MODEL, verbose_name=_("Subscriber"),
related_name="subscriptions_set")
membership = models.ForeignKey(Membership, verbose_name=_("Membership"),
related_name="subscriptions_set")
created = models.DateTimeField(_("Created"), auto_now_add=True)
last_updated = models.DateTimeField(_("Last updated"), auto_now=True)
active = models.BooleanField(_("Active"), default=True)
class Membership(models.Model):
name = models.CharField(_("Name"), max_length=15)
slug = models.SlugField(_("Slug"), max_length=15, unique=True)
price = models.DecimalField(_("Price"), max_digits=6, decimal_places=2)
recurring = models.BooleanField(_("Recurring"))
duration = models.PositiveSmallIntegerField(_("Duration months"))
class Content(models.Model):
author = models.ForeignKey(AUTH_USER_MODEL, verbose_name=_("Author"),
related_name="contents_set")
title = models.CharField(_("Title"), max_length=50)
slug = models.SlugField(_("Slug"), max_length=70, unique=True)
content = RichTextField(_("Content"))
date = models.DateField(_("Date"), default=timezone.now)
published = models.BooleanField(_("Published"))