在Django Admin中为模型上的“注释”或“注释”表单

时间:2013-03-01 19:05:38

标签: django django-models django-admin

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

基本上我想在django admin中为特定模型添加评论表单。

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

第2轮(编辑)

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

how my admin looks now

它增加了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)

我的用户模型处理管理员用户,是我想要添加笔记功能的。如何在创建日期前添加登录用户名?

5 个答案:

答案 0 :(得分:2)

我不知道“覆盖整个视图”是什么意思,因为这样的事情使得Django如此使用起来非常好,能够在没有太多麻烦的情况下使用额外的功能。假设我不打算把我的整只脚放进嘴里,这就是我接近它的方式:

添加注释应该不会太困难,只需在cars.models中定义另一个模型并添加Notes之类的内容。然后让这个模型参考汽车模型,因为它的外键和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管理面板的一种设计特性 - 它应该用于修改表格,而不一定是最终用户输入面板。

再一次头痛: Django的syncdb不会更改已存在的表,因此如果要在现有模型中添加/删除列,则需要删除并重新创建表,或使用django-evolution之类的内容。然而,使用它是另一个问题。

答案 1 :(得分:1)

我知道这是一篇旧帖子,但万一有人到达这里,这是我的解决方案,灵感来自Django: How to get current user in admin forms

models.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)

admin.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,并使用它来填充" user" BaseGenericInlineFormSet.save_new()中的字段。这样就可以正确记录登录用户。其他代码只是为了让它更多"评论"喜欢。例如,只读字段,不删除等

注2:这是一个通用解决方案,因此无论我们想要评论哪种模式,只需添加

即可
inlines = [CommentInline,]

到管理类,我们很高兴。

答案 2 :(得分:1)

这是一个老问题,但我在他的回答中,由Dryice Liu的作品制作了一个受到很大启发的包。

该包名为django-admin-comments。它很容易设置:

安装Django管理员评论:

$ pip install django-admin-comments

将其添加到您的INSTALLED_APPS

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

运行数据库迁移

$ manage.py migrate

现在,只需将CommentInline添加到任何ModelAdmin

即可
from admin_comments.admin import CommentInline

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

那就是它!

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

答案 3 :(得分:0)

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

date = models.DateTimeField('date', help_text="This is a help text")

答案 4 :(得分:-1)

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

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