Django用户外键,save_model和save_formset

时间:2011-03-30 05:18:10

标签: django forms models

我有一些关于从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(用户)。我已尝试通过在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文档,但他们并没有完全回答我的问题。任何启蒙都会受到高度赞赏。

1 个答案:

答案 0 :(得分:7)

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

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方法,它与您form中的views.py无关。当正在编辑的对象的save_model已经过验证时,ModelAdmin会调用ModelForm

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,我应该怎么做   纠正吗?一些示例代码将是   很有帮助。

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

希望有所帮助!