【问题标题】:How to auto insert the current user when creating an object in django admin?在 django admin 中创建对象时如何自动插入当前用户?
【发布时间】:2023-03-03 08:16:25
【问题描述】:

我有一个文章数据库

submitter = models.ForeignKey(User, editable=False)

其中User导入如下:

from django.contrib.auth.models import User. 

我想在特定用户提交文章时将当前活跃用户自动插入提交者字段。

有人有什么建议吗?

【问题讨论】:

  • 你的意思是用于管理还是前端?
  • 我想在 django 管理站点中使用

标签: python django django-admin


【解决方案1】:

以防万一有人在寻找答案,这是我在这里找到的解决方案: http://demongin.org/blog/806/

总结一下: 他有一个作文表如下:

from django.contrib.auth.models import User

class Essay(models.Model):
    title = models.CharField(max_length=666)
    body = models.TextField()
    author = models.ForeignKey(User, null=True, blank=True)

其中多用户可以创建论文,所以他创建了一个admin.ModelAdmin类,如下:

from myapplication.essay.models import Essay
from django.contrib import admin

class EssayAdmin(admin.ModelAdmin):
    list_display = ('title', 'author')
    fieldsets = [
        (None, { 'fields': [('title','body')] } ),
    ]

    def save_model(self, request, obj, form, change):
        if getattr(obj, 'author', None) is None:
            obj.author = request.user
        obj.save()

【讨论】:

  • 这仅适用于作者的 null=True。没有它,我会从“getattr”行中得到“raise self.field.rel.to.DoesNotExist”。我可以要求 null=False 吗?
  • 您也可以添加'if not change:'来处理条目创建的情况。 'else' 表示是否正在修改。
【解决方案2】:

假设用户 B 保存了用户 A 创建的记录。通过使用上面的这种方法,记录将与用户 B 一起保存。在某些情况下,这可能不是最佳选择,因为保存该记录的每个用户都将“偷”它。有一种解决方法,它只会保存用户一次(创建它的人):

models.py

from django.contrib.auth.models import User

class Car(models.Model):
    created_by = models.ForeignKey(User,editable=False,null=True,blank=True)
    car_name = models.CharField(max_length=40)

admin.py

from . models import *

class CarAdmin(admin.ModelAdmin):
    list_display = ('car_name','created_by')
    actions = None

    def save_model(self, request, obj, form, change):
        if not obj.created_by:
            obj.created_by = request.user
        obj.save()

【讨论】:

  • 你必须检查 if not obj.created_by_id 而不是 if not obj.created_by (Django 3.0.5)。
【解决方案3】:

如果你不想在你的模型中保留外键给用户,那么在你的admin.py覆盖保存方法中

obj.author = request.user.username
obj.save()

这将存储登录到您的数据库的用户名。

【讨论】:

  • 是的,这会起作用,但这也是某些网站不允许您更改用户名的原因。 :(
【解决方案4】:

是时候寻找更好的解决方案来覆盖 get_form 方法了

假设我们有这个模型

models.py

from django.db import models
from django.contrib.auth.models import User


class Post(models.Model):
    title = models.CharField(max_length=256)
    content = models.TextField()
    author = models.ForeignKey(User, on_delete=models.CASCADE)


    def __str__(self):
        return self.title

admin.py

class PostAdmin(admin.ModelAdmin):
    # you should prevent author field to be manipulated 
    readonly_fields = ['author']

    def get_form(self, request, obj=None, **kwargs):
        # here insert/fill the current user name or id from request
        Post.author = request.user
        return super().get_form(request, obj, **kwargs)


    def save_model(self, request, obj, form, change):
        obj.author = request.user
        obj.last_modified_by = request.user
        obj.save()


admin.site.register(Post, PostAdmin)

【讨论】:

  • ModelAdmin.get_form 返回一个表单类而不是一个表单实例,因此它并不适合设置任何特定的表单字段(对于绑定的表单,这将保存对象)。此外,您似乎正在设置 Post 类级别属性,我认为这不会做任何事情。 save_model 实现确实是要走的路(你不需要同时设置 obj.author 和 obj.authori_id,Django 会在后台处理 id)。
【解决方案5】:

根据http://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.prepopulated_fields,您不能将 ForeignKey 与 prepopulated_field 管理指令一起使用,唉

但是this thread 可能会对您有所帮助。在我的回答中,我还链接到 Google 扫描的 Pro Django 版本,它为这类事情提供了很好的解决方案。理想情况下,如果你能买这本书肯定会更好,但谷歌似乎有大部分相关章节。

【讨论】:

    猜你喜欢
    • 2019-02-13
    • 1970-01-01
    • 2020-07-09
    • 1970-01-01
    • 1970-01-01
    • 2015-03-31
    • 2013-02-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多