4

基本上,我想要一种让管理员对正在查看的模型发表评论的方法。假设我们有一辆汽车模型,我已经在管理站点中注册了,我想让其他管理员写一个关于这辆车的简短说明,并让它只显示在管理界面中,以及他们的名字和时间戳。

本质上,我想在 django 管理员中为特定模型添加评论表单。

关于如何在不覆盖整个视图的情况下执行此操作的任何建议?

第 2 轮(编辑)

这是我使用 GordonsBeards 答案的进展。

我的管理员现在的样子

它添加了 3 个“额外”的空笔记,这不是破坏交易,但仍然很有趣。

# In models.py
class Note(models.Model):
    user = models.ForeignKey(User)
    note = models.TextField()
    created_on = models.DateTimeField(auto_now_add=True)

    def __unicode__(self):
        return "created on: {}".format(self.created_on)

我的用户模型同时处理管理员用户,并且是我想要添加注释功能的对象。如何在创建日期前添加登录用户名?

4

5 回答 5

2

我不知道您所说的“覆盖整个视图”是什么意思,因为这种事情使 Django 使用起来非常漂亮,能够在不费吹灰之力的情况下增加额外的功能。假设我不打算把整个脚放进嘴里,我会这样处理它:

添加注释应该不会太困难,只需在您的内部定义另一个模型cars.models并添加类似Notes. 然后让这个模型引用 Cars 模型,因为它是外键和 zippozappo - 你已经得到了一些注释。

至于将其“限制”为仅管理员,除非您的公共视图允许人们添加注释或显示注释,否则它不应该出现在管理应用程序之外。

网站/models.py

from django.contrib.auth.models import User
# snip your stuff...
class Notes(models.Model)
    user = models.ForeignKey('auth.User')
    author = models.ForeinKey('auth.User')
    note = models.TextField()
    created_on = models.DateTimeField(auto_now_add=True)

确保./manage syncdb在此之后!

站点/admin.py

from site.models import Notes
from django.contrib.auth.models import User

class NotesInline(admin.StackedInline):
    model = Notes
    extra = 0

class UserAdmin(UserAdmin):
    inlines = [NotesInline,]

admin.site.unregister(User)
admin.site.register(User, UserAdmin)

以下是使用内联管理内容的一些注意事项,以防您想自定义每辆车末尾的注释显示:https ://docs.djangoproject.com/en/dev/ref/contrib/admin/#django .contrib.admin.ModelAdmin.inlines

当然,您可以根据自己的喜好扩展/更改/更改它,但是您不必做任何棘手的事情来为模型添加一些额外的功能。

理想情况下,您会创建一个 Notes 应用程序,它可以让您评论您想要的任何对象,而不仅仅是用户。

编辑

class NotesInline现在有一个extra=0。这将停止默认情况下在用户页面上显示 3 条记录。

class Notes上面有一个author = models.ForeinKey('auth.User'),您需要首先跟踪谁留下了笔记。这将添加一个下拉框,让您选择留下笔记的人。如果我理解正确,您希望当前登录的用户自动填写此字段。强制这样做的问题在于,在管理面板上,所有管理员都是平等创建的(除非受权限限制),因此将此author字段限制为当前登录的用户将需要比您应该费心的更多修补。

如果您需要将管理面板扩展到您希望自动填写这些字段的位置,则必须创建一些其他公共视图,然后将访问权限限制为有权访问它的用户。否则,您将不得不自己开始覆盖管理视图/模板。这是 Django 管理面板的一种设计特性——它应该用于修改您的表格,不一定是最终的用户输入面板。

还有一个让人头疼 的问题:Djangosyncdb不会改变已经存在的表,所以如果你想从现有模型中添加/删除一列,你需要删除并重新创建表,或者使用类似django-evolution 的东西。然而,使用它是另一个问题。

于 2013-03-01T19:20:17.503 回答
2

我知道这是一篇旧帖子,但以防万一有人到达这里,这是我的解决方案,受Django 启发:如何在管理表单中获取当前用户

模型.py:

class Comment(models.Model):
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content_object = GenericForeignKey("content_type", "object_id")
    user = models.ForeignKey(User)
    content = models.TextField()
    time = models.DateTimeField(auto_now_add=True)

管理员.py:

class CommentInlineForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(CommentInlineForm, self).__init__(*args, **kwargs)
        instance = getattr(self, 'instance', None)
        if instance and instance.pk:
            self.fields['content'].widget.attrs['readonly'] = True


class CommentInlineFormset(BaseGenericInlineFormSet):
    def save_new(self, form, commit=True):
        setattr(form.instance, "user", self.current_user)
        return super(CommentInlineFormset, self).save_new(
            form, commit=True)


class CommentInline(GenericTabularInline):
    model = Comment
    extra = 1
    form = CommentInlineForm
    formset = CommentInlineFormset
    readonly_fields = ('user', 'time')

    def has_delete_permission(self, request, obj=None):
        return False

    def get_formset(self, request, obj=None, **kwargs):
        formset = super(CommentInline, self).get_formset(
            request, obj, **kwargs)
        formset.current_user = request.user
        return formset

注1:这里的关键是覆盖GenericTabularInline.get_formset()传入request.user,并用它来填充BaseGenericInlineFormSet.save_new()中的“user”字段。以便正确记录登录用户。其他代码只是为了使它更像“评论”。例如,只读字段,不删除等。

注2:这是一个通用的解决方案,所以无论我们要评论哪个模型,只需添加

inlines = [CommentInline,]

到管理班,我们很高兴。

于 2015-05-20T01:50:01.993 回答
2

这是一个老问题,但我在Dryice Liu 的回答中深受启发,制作了一个软件包。

该包称为django-admin-comments. 设置起来非常容易:

安装 Django 管理员评论:

$ pip install django-admin-comments

将其添加到您的INSTALLED_APPS

INSTALLED_APPS = (
    ...
    'admin_comments',
    ...
)

运行数据库迁移

$ manage.py migrate

现在,只需CommentInlineModelAdmin

from admin_comments.admin import CommentInline

class MyModelAdmin(admin.ModelAdmin):
    model = MyModel
    inlines = [CommentInline,]

就是这样!

欢迎请求请求,如果此线程上的任何人想成为贡献者,只需打开一个 PR,将自己添加到贡献者列表中,我会接受并添加你。

于 2018-01-15T01:59:09.027 回答
1

对于注释,您现在可以添加帮助文本:

date = models.DateTimeField('date', help_text="This is a help text")
于 2018-06-08T22:27:02.103 回答
-1

如果不深入管理,最简单的方法是使用 javascript 将评论表单注入管理界面。您需要创建一个模型来存储评论(您可能可以使用内置的评论系统,尽管这可能比它的价值更麻烦),一些用于检索和保存评论的 ajax,以及一个 javascript 小部件,它将呈现检索到的评论和评论表单。

然后,您只需要在管理模板中包含对脚本的引用,而不必触及任何管理员内部。

于 2013-03-01T19:15:09.807 回答