从用户创建的对象中获取站点特定的用户配置文件字段

Get site-specific user profile fields from user-created object

我正在使用 Django sites framework (Django 2.1) 将应用拆分为多个站点。除了 User 模型之外,我的所有模型都是特定于站点的。这是我的 Post 模型:

post.py

class Post(models.Model):
    parent = models.ForeignKey(
        'self',
        on_delete=models.CASCADE,
        related_name='children',
        related_query_name='child',
        blank=True,
        null=True,
    )
    title = models.CharField(
        max_length=255,
        blank=True,
    )
    body_raw = models.TextField()
    body_html = models.TextField(blank=True)
    user = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
    )
    site = models.ForeignKey(Site, on_delete=models.CASCADE)
    on_site = CurrentSiteManager()

我可以毫无问题地按站点分隔 post。当我想得到 posts 时,我调用:

posts = Post.on_site.filter(...)

我有一个名为 UserProfile 的单独模型。它是一个多对一的配置文件,其中为每个用户站点组合创建了一个唯一的配置文件(类似于 SE 的配置文件实现)。配置文件有一个 reputation 属性,我想在获得任何 post 时访问该属性。这个 reputation 属性对于每个站点都应该不同(比如在 SE 上,你在每个站点上的代表如何不同)。

user_profile.py

class UserProfile(models.Model):
    user = models.ForeignKey(get_user_model(), on_delete=models.CASCADE)
    reputation = models.PositiveIntegerField(default=1)
    site = models.ForeignKey(Site, on_delete=models.CASCADE)
    on_site = CurrentSiteManager()

当我得到Post来自查询?

我想做这样的事情:

Post.on_site.filter(...)
    .select_related('user__userprofile')
    .filter_related(user__userprofile.site == get_current_site())

如何过滤多对一相关模型?

最好让 UserProfile -> User 关系成为 OnetoOne,
因为 Django 不知道要显示许多配置文件中的哪一个

(但你还需要定义related_name

models.OneToOneField(get_user_model(), related_name='userprofile_rev')

那你就可以做到了

qs = Post.on_site.filer().select_related('user', 'user__userprofile_rev')
for post in qs:
    print(post.user.username, post.user.userprofile_rev.reputation)

如果你不想改变你的数据库结构,你可以这样做
(但你需要指定要return的配置文件)

qs = Post.on_site.filer().select_related('user').prefetch_related('user__userprofile_set')
for post in qs:
    print(post.user.username, post.user.userprofile_set[0].reputation)