I have a few things about saving logged in user, save_model() and save_formset() from Django's modelAdmin that I would like to ask about.
Consider that I have a model which takes in a photo that a user uploads through http POST.
In 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
Then in my views.py:
def upload(request):
form = photoForm(request.POST, request.FILES)
if form_is_valid():
#do something useful
form.save()
Here I have an interesting scenario. The form in my views.py is not valid as the ['uploader'] field in models never gets updated, and it is a required field, and so it will not save.
1) How do I get the form to be validated?
Also when saving the form, I have seen a post here which teaches how to save ForeignKey(User) using the save_model() in modelAdmin. I've tried overiding this as shown in the link, by creating a photoAdmin class in my admin.py:
class photoAdmin(admin.ModelAdmin):
def save_model(self, request, obj, form, change):
if not change:
obj.uploader = request.user
obj.save()
but it could still could not save the uploader field with request.user or request.user.username. I tried overiding save_formset() as well since I am using the photoForm in my views.py. Still no avail.
2) When do save_model() and save_formset() actually get called?
3) What is difference between save_formset() and save_model()?
4) Will save_model() or save_formset() be evoked when I simply call form.save() in the views.py above?
5) What is wrong with my approach in both validating the form in views.py as well as saving the uploader field with request.user, and how should I correct 开发者_开发技巧it? Some sample codes would be of great help.
I have read the Django docs on Admin site, but they do not exactly answer my questions. Any enlightenment would be greatly appreciated.
Let's deal with your first question about your view. As you say, it's not a valid form because uploader isn't supplied. Exclude the user field from your ModelForm
with the exclude
Meta class attribute (since we're planning to auto insert it).
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.
Your second question about ModelAdmin:
No, save_model()
is a ModelAdmin
method, it has nothing to do with your form
in your views.py
. save_model
is called on a ModelAdmin
when the ModelForm
for the object being edited has validated.
Your code for ModelAdmin
should work as you have it, unless your form threw some errors. You would have to tell me what errors you got if you want further advice!
2) When do save_model() and save_formset() actually get called?
Both after forms and formsets are validated.
3) What is difference between save_formset() and save_model()?
save_model
is for the model being edited i.e. whatever model you registered your ModelAdmin with
save_formset
is for saving the formsets (ModelAdmin.inlines
)
4) Will save_model() or save_formset() be evoked when I simply call form.save() in the views.py above?
No, why would they? They are completely unrelated to your views.py forms. save_model() is a ModelAdmin
method, not a Form
method.
5) What is wrong with my approach in both validating the form in views.py as well as saving the uploader field with request.user, and how should I correct it? Some sample codes would be of great help.
As you said, the validation is failing because uploader is required. Take my code example above to prevent the validation errors if you are always planning to set the uploader field.
Hope that helps!
精彩评论