【问题标题】:Referencing extended manytomany User model in Django...?在 Django 中引用扩展的多用户模型...?
【发布时间】:2017-11-18 05:41:08
【问题描述】:

我在引用模板中的扩展用户模型 (UserProfile) 时遇到了一些问题。

我设置的是当前登录的用户将是与该评论关联的“用户对象”。我这样做如下:

admin.py:

class CommentAdmin(admin.ModelAdmin):
    list_display = ('created_by', 'post', 'created', 'active')
    list_filter = ('active', 'created')
    search_fields = ('created_by', 'body')

    def save_model(self, request, obj, form, change):
        instance = form.save(commit=False)
        if not hasattr(instance,'created_by'):
            instance.created_by = request.user
        instance.save()
        form.save_m2m()
        return instance

    def save_formset(self, request, form, formset, change):

        def set_user(instance):
            if not instance.created_by:
                instance.created_by = request.user
            instance.save()

        if formset.model == Comment:
            instances = formset.save(commit=False)
            map(set_user, instances)
            formset.save_m2m()
            return instances
        else:
            return formset.save()

我的评论模型如下:

class Comment(models.Model):
    created_by = models.OneToOneField(User, related_name='created_by', null=True, blank=True)
    post = models.ForeignKey(Post, related_name='comments')
    body = models.TextField()
    created = models.DateTimeField(auto_now_add=True)
    active = models.BooleanField(default=True)

    class Meta:
        ordering = ('created',)

    def __str__(self):
         return "Comment by {} on {}".format(self.created_by, self.post)

我的 UserProfile 模型扩展了 User 模型如下:

class UserProfile(models.Model):
    user = models.OneToOneField(User, related_name='userprofile')
    user_avatar = models.ImageField(storage=site_media_upload_location, null=True, blank=True)

一切正常。我可以保存 cmets 并将所有 cmets 关联到登录的用户实例。我现在遇到的问题是:我想为与每个评论关联的用户(而不是当前登录的用户)显示 user_avatar(在 UserProfile 模型中定义)。

到目前为止,我已经尝试了以下方法:

<img src="{{ MEDIA_URL }}{{ comment.created_by.user.userprofile.user_avatar.url }}">

<img src="{{ MEDIA_URL }}{{ comment.created_by.userprofile.user_avatar.url }}">

但似乎没有任何效果(最后的猜测更多的是绝望而不是实际的可能性)。

那么,根据上述模型 - 以及评论是使用当前记录的用户对象的实例创建的知识 - 我如何让这一切正常工作?

我唯一的另一个想法是我可能需要在 cmets 模型中添加类似的内容:

class Comment(models.Model):
    commenter_avatar = models.OneToOneField(UserProfile.user_avatar, related_name='user_avatar', null=True, blank=True)

也许我可以在 cmets admin save() 方法中请求 user.userprofile.user_avatar?

【问题讨论】:

    标签: django django-models django-forms django-templates django-views


    【解决方案1】:
    class UserProfile(models.Model):
        user = models.OneToOneField(User, related_name='userprofile')
        user_avatar = models.ImageField(upload_to="images/") // no need null=True, blank=True
    
    class Comment(models.Model):
        created_by = models.ForeignKey(UserProfile, related_name='created_by', null=True, blank=True)
        post = models.ForeignKey(Post, related_name='comments')
        body = models.TextField()
        created = models.DateTimeField(auto_now_add=True)
        active = models.BooleanField(default=True)
    
        class Meta:
            ordering = ('created',)
    
        def __str__(self):
             return "Comment by {} on {}".format(self.created_by, self.post)
    
    
    <img src="{{ MEDIA_URL }}{{ comment.created_by.user_avatar.url }}">
    

    我认为您使用过多的 USER 关系会简化您的代码。 试试看!!

    【讨论】:

    • 是的 - 将 Comments 模型链接到“扩展用户” UserProfile 模型是非常纯粹的 - 但是,在代码的更下方,我将需要扩展到 User 模型 - 例如,Comment by {{ comment.created_by.user.username }} on {{ comment.created }}
    【解决方案2】:

    图像字段的url 属性已添加MEDIA_URL,请参阅https://docs.djangoproject.com/en/1.11/topics/files/#using-files-in-models

    所以最后的标签应该是:

    <img src="{{ comment.created_by.userprofile.user_avatar.url }}">
    

    如果用户个人资料确实有图片

    【讨论】:

    • 太棒了——这成功了!我不确定为什么会这样 - 当我保存评论时,我使用 User 实例。所以我当然需要说“找到评论,找到它是由谁创建的(这是一个用户)......所以进入那个用户并找到他们的用户配置文件然后找到他们的 user_avatar.url......除非 created_by 和用户并排序相互关系的(它们是相同的吗?)
    • 你在created_by中引用了User对象,每个User对象通过userprofile相关属性都有一个UserProfile的外键。然后在模板中,ORM 只需遵循对用户的引用,然后是 UserProfile,然后是图像
    • 所以 user 和 created_by 是相同的之一(OneToOneField),然后我们可以从其中一个跳到 UserProfile。有点道理。您认为最好覆盖默认的 Django 用户模型吗?我读到有些人说是,有些人说不是……就像 Django 的全部意义不是重新发明轮子。
    • 如果您之前已经开始您的项目,请不要费心迁移到另一个用户模型。在其他情况下,我已经使用 AUTH_USER_MODEL 覆盖了一段时间,它让事情变得更清晰
    猜你喜欢
    • 2011-07-17
    • 2016-10-12
    • 2011-02-28
    • 2013-12-06
    • 2018-01-21
    • 1970-01-01
    相关资源
    最近更新 更多