Django消息/通知(如果连接的模型不存在/已更改)

时间:2018-07-12 13:58:27

标签: python django

我有一个Profile模型,它是与OnetoOne模型的User关系。

我想告诉用户他们的个人资料不完整,并要求他们动态填写某些详细信息。

例如,我有一个Location模型,它是OneToOne的{​​{1}}。

Profile

用户注册后,我们尚未将class Profile(models.Model): # some fields e.g. name class Location(models.Model): profile = models.OneToOneField(Profile, on_delete=models.CASCADE, null=True) # longitude = ... # latitude = ... 实例连接到location。我想显示的是顶部的django消息/错误栏,如果profile不具有profile属性,则指示用户完成配置文件。

我不确定应该如何进行: 我认为一种方法是将location布尔字段添加到completed_setup类中。如果用户现在决定删除Profile,我们还将更新此字段并将其设置为location

False

另一种方法是在模板中包含以下内容:

{% if profile.completed_setup %}{% else %}
<p>Finish Building Your Profile</p>
{% endif %}

我正在寻找最有效,最正确的方法,因为我拥有更多的关联模型(而不仅仅是位置)。

1 个答案:

答案 0 :(得分:2)

我将使用添加到Profile模型的属性而不是新字段。由于completed_setup很可能是计算值,因此可以使用属性的getter来提供completed_setup的值。有两种选择。首先,您可以尝试获取OneToOne字段,如果该字段不存在,则返回False。您可以针对多个字段执行此操作

#models.py
class Profile(models.Model):
    # some fields e.g. name
    @property
    def completed_setup(self):
        try:
            Location.objects.get(profile_id=self.id)
            AnotherModel.objects.get(profile_id=self.id)
        except (Location.DoesNotExist, AnotherModel.DoesNotExist):
            return False
        else:
            return True

#template
{% if profile.completed_setup %}{% else %}
    <p>Finish Building Your Profile</p>
{% endif %}

您还可以使用相关名称来检查其是否可能比上述名称更可靠。也可以对多个字段执行此操作。

#models.py
class Profile(models.Model):
    # some fields e.g. name
    @property
    def completed_setup(self):
        if self.location and self.another_onetoone:
            return True
        else:
            return False

class Location(models.Model):
    profile = models.OneToOneField(Profile, related_name='location', on_delete=models.CASCADE, null=True)
    # longitude = ...
    # latitude = ...

#template
{% if profile.completed_setup %}{% else %}
    <p>Finish Building Your Profile</p>
{% endif %}

在您对其中一个问题的评论中,您希望能够对多个组运行查询。这是一种方法。如果您像我对objects.all()那样进行传递,则建议对queryset使用prefetch_related进行此操作。第一种解决方案对于大型数据库而言并不理想。第二个对一个对象有好处。以下是针对completed_setup进行过滤的最佳解决方案。

#models.py
class Profile(models.Model):
    # some fields e.g. name
    @property
    def completed_setup(self):
        if self.location and self.another_onetoone:
            return True
        else:
            return False

    @classmethod
    def filter_completed_setup(cls, queryset=None, completed_setup=True):
        match_ids = []
        if not queryset:
            queryset = cls.objects.all().prefetch_related('location', 'another_onetoone')
        else:
            queryset = queryset.prefetch_related('location', 'another_onetoone')
        assert queryset.model is cls, "queryset must be of class Profile"
        for p in queryset:
            if completed_setup:
                if p.location and p.another_onetoone:
                    match_ids.append(p.id)
            else:
                if not (p.location or p.another_onetoone):
                    match_ids.append(p.id)
        return cls.objects.filter(id__in=match_ids)

Profile.filter_completed_setup(queryset or None, completed_setup=False)