【问题标题】:Django User Foreignkey, save_model and save_formsetDjango 用户外键、save_model 和 save_formset
【发布时间】:2011-07-25 19:51:30
【问题描述】:

我有一些关于从 Django 的 modelAdmin 保存登录用户、save_model() 和 save_formset() 的问题,我想问一下。

假设我有一个模型,它接收用户通过 http POST 上传的照片。

在models.py中:

class photo(models.Model):
    title = models.CharField(max_length=50)
    img = models.ImageField(upload_to='photocollection')
    uploader = models.ForeignKey(User)
    latitude =  models.FloatField(null=True, blank=True)
    longitude = models.FloatField(null=True, blank=True)

    def save(self):
        #Retain the model instance to do some processing before saving:
        self.latitude = exif.getGPSLatitude(self.img)
        self.longitude = exif.GPSLongitude(self.img)
        return super(photoCollection, self).save()

class photoForm(ModelForm):
    class Meta:
        model = photo

然后在我的views.py中:

def upload(request):
    form = photoForm(request.POST, request.FILES)

    if form_is_valid():
       #do something useful
       form.save()

这里有一个有趣的场景。我的 views.py 中的表单无效,因为模型中的 ['uploader'] 字段永远不会更新,它是必填字段,因此不会保存。

1) 如何让表单得到验证?

另外,在保存表单时,我看到了一个帖子here,它教了如何在 modelAdmin 中使用 save_model() 来保存 ForeignKey(User)。我已经尝试通过在我的 admin.py 中创建一个 photoAdmin 类来覆盖它,如链接所示:

class photoAdmin(admin.ModelAdmin):
   def save_model(self, request, obj, form, change):
       if not change:
           obj.uploader = request.user
       obj.save()

但它仍然无法使用 request.user 或 request.user.username 保存上传者字段。我也尝试覆盖 save_formset(),因为我在 views.py 中使用了 photoForm。还是没用。

2) save_model() 和 save_formset() 何时真正被调用?

3) save_formset() 和 save_model() 有什么区别?

4) 当我在上面的views.py 中简单地调用form.save() 时会调用save_model() 或save_formset() 吗?

5) 我的方法在验证 views.py 中的表单以及使用 request.user 保存上传者字段时有什么问题,我应该如何更正它?一些示例代码会很有帮助。

我已经阅读了Admin site 上的 Django 文档,但它们并没有完全回答我的问题。任何启示将不胜感激。

【问题讨论】:

    标签: django forms models


    【解决方案1】:

    让我们来处理关于您的观点的第一个问题。正如你所说,它不是一个有效的表格,因为没有提供上传器。使用 exclude 元类属性从您的 ModelForm 中排除用户字段(因为我们计划自动插入它)。

    class photoForm(ModelForm):
        class Meta:
            model = photo
            exclude= ('uploader',)
    
    if form_is_valid(): # uploader has been excluded. No more error.
        photo = form.save(commit=False) # returns unsaved instance
        photo.uploader = request.user
        photo.save() # real save to DB.
    

    关于 ModelAdmin 的第二个问题:

    不,save_model() 是一个ModelAdmin 方法,它与你views.py 中的form 无关。当正在编辑的对象的 ModelForm 已验证时,save_model 将在 ModelAdmin 上调用。

    您的ModelAdmin 代码应该可以正常工作,除非您的表单出现错误。如果您需要进一步的建议,您必须告诉我您遇到了什么错误!


    2) 什么时候做 save_model() 和 save_formset() 真的被调用了吗?

    表单和表单集都经过验证。

    3) 有什么区别 save_formset() 和 save_model()?

    save_model 用于正在编辑的模型,即您注册 ModelAdmin 时使用的任何模型

    save_formset 用于保存表单集 (ModelAdmin.inlines)

    4) 将 save_model() 或 save_formset() 当我简单地打电话时被唤起 上面views.py中的form.save()?

    不,他们为什么要这样做?它们与您的 views.py 表单完全无关。 save_model() 是 ModelAdmin 方法,而不是 Form 方法。

    5) 我的方法有什么问题 都在 views.py 中验证表单 以及保存上传者字段 与 request.user,我应该如何 正确吗?一些示例代码将是 有很大帮助。

    正如您所说,验证失败,因为需要上传器。如果您总是计划设置上传者字段,请以我上面的代码示例来防止验证错误。

    希望有帮助!

    【讨论】:

    • 谢谢!那成功了。很抱歉这些奇怪的问题,但似乎我对 ModelAdmin 中的 save_models 有误解。我认为它与从views.py 创建的模型有关,并且每次创建模型时都会被调用。不过,我仍然不太清楚您会在何处以及在什么情况下调用 AdminModel 类。是不是只在做与Django的管理站点(/admin/)相关的事情时使用?
    • ModelAdmin 仅限于管理站点。只有 django.contrib.admin 调用模型管理员。
    • 哦,是的!经过 2 小时的摆弄,您的示例成功了!你这个男人。
    猜你喜欢
    • 1970-01-01
    • 2012-06-12
    • 1970-01-01
    • 2011-03-02
    • 2019-07-02
    • 2020-02-18
    • 2021-06-13
    • 1970-01-01
    • 2021-09-14
    相关资源
    最近更新 更多