从外键django查询父级

Querying Parent from the foreign key django

我有以下型号:

class CustomUser(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(unique=True)
    first_name = models.CharField(max_length=32)
    last_name = models.CharField(max_length=32)
    is_staff = models.BooleanField(default=False)
    is_active = models.BooleanField(default=True)
    date_joined = models.DateTimeField(default=timezone.now)

    USERNAME_FIELD = 'email' # unique identifier, changed to email (default was username)
    REQUIRED_FIELDS = ['first_name', 'last_name']

    objects = CustomUserManager() # custom manager for interacting with database

    def __str__(self):
        return self.email

class Refer(models.Model) :
    referred_by = models.ForeignKey(CustomUser, on_delete=models.CASCADE, default='admin', related_name='referred_by')
    referrals = models.ManyToManyField(CustomUser, related_name='referrals', blank=True)
    unique_ref_id = models.CharField(max_length=8, blank=True, default=generate())

    def __str__(self) :
        return f'Referred By: {self.referred_by}'

我想用这个实现推荐系统,我有 unique_for_id 字段(示例 'exbvagtl'),我如何在该用户下创建新的推荐?

类似于:Refer.objects.create(referred_by= CustomUser.objects.get(Refer__unique_ref_id='exbvagtl'))

非常欢迎更好的模型设计、资源和改进!

我认为你把事情复杂化了。通过创建具有 ForeignKeyCustomUserRefer 对象,这意味着每个 CustomUser 可以有零个、一个或多个 Refer 对象。虽然这并非不可能管理,但它使它变得更难,因为现在您的视图将需要确保您正在使用正确的 Refer 对象,或者必须 "concatenate" 这些。此外,这意味着 CustomUser 可以有多个 unique_ref_ids.

问题是为什么我们首先需要这样的对象。您可以简单地在 CustomUser 对象上构造一个 unique_ref_id,然后将 ForeignKey 添加到 'self' 以指定推荐人是什么:

class CustomUser(PermissionsMixin, AbstractBaseUser):
    email = models.EmailField(unique=True)
    first_name = models.CharField(max_length=32)
    last_name = models.CharField(max_length=32)
    is_staff = models.BooleanField(default=False)
    is_active = models.BooleanField(default=True)
    date_joined = models.DateTimeField(auto_now_add=True)
    <b>unique_ref_id</b> = models.CharField(max_length=8, blank=True, default=generate)
    <b>referred_by</b> = models.ForeignKey(
        'self',
        related_name='referrals',
        null=True,
        default=None,
        on_delete=models.SET_NULL
    )

    USERNAME_FIELD = 'email' # unique identifier, changed to email (default was username)
    REQUIRED_FIELDS = ['first_name', 'last_name']

    objects = CustomUserManager() # custom manager for interacting with database

    def __str__(self):
        return self.email

因此,我们可以在此处添加由另一个用户引用的用户:

CustomUser.objects.create(<b>referred_by_id=id_of_referred_user</b>)

如果稍后删除 referred_by 用户,则它将设置为 NULL

您还可以查询用户推荐的用户:

myuser<b>.referrals.all()</b>

问题出在您对推荐系统的设计上。通常,在推荐系统中,一个用户有一个 referral_id。但是您的设计建议一个用户可以拥有多个 referral_id。

我建议您将 unique_ref_id 移动到 CustomUser 模型。这样你就可以做这样的事情:

Refer.objects.create(referred_by=CustomUser.objects.get(unique_ref_id="exbvagtl"))

第二个建议:把所有东西都放在一个table

你会注意到提到另一个人的人也是一个人,所以它基本上是在提到自己。在这方面,您可以让您的 CustomUser 模型如下所示:

class CustomUser(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(unique=True)
    first_name = models.CharField(max_length=32)
    last_name = models.CharField(max_length=32)
    is_staff = models.BooleanField(default=False)
    is_active = models.BooleanField(default=True)
    date_joined = models.DateTimeField(default=timezone.now)
    referred_by = models.ForeignKey(self, on_delete=models.SET_NULL, blank=True, null=True)
    unique_ref_id = models.CharField(max_length=8, blank=True, default=generate())

    USERNAME_FIELD = 'email' # unique identifier, changed to email (default was username)
    REQUIRED_FIELDS = ['first_name', 'last_name']

    objects = CustomUserManager() # custom manager for interacting with database

    def __str__(self):
        return self.email

基于此,您可以执行以下操作:

创建新用户:

sponsor = CustomUser.objects.get(unique_ref_id="exbvagtl")
user = CustomUser(email=email, first_name=first_name, last_name=last_name,referred_by=sponsor)
user.save()

获取用户推荐列表:

sponsor = CustomUser.objects.get(unique_ref_id="exbvagtl")
referrals = CustomUser.objects.filter(referred_by=sponsor)

希望对您有所帮助,如果您有任何疑问,请随时在下方提问。