Question

I'm trying to handle an image upload with the following code:

    location = get_object_or_404(Location, slug=slug)
    if 'submit_photo' in request.POST:
    photo = PhotoForm(request.POST, request.FILES)
    if photo.is_valid():
        new_photo = photo.save(commit=False)
        new_photo.location = location
        new_photo.user = request.user
        new_photo.save()
        photo.save_m2m() 
    else:
        print(photo.errors)

When I try to upload I get the validation error that the location is a required field (which it is). But I thought the point of commit=False is so I could add information before anything gets saved, such as required fields...

I'm sure I'm missing something really stupid because I have this copied almost exactly from other working form submits. I have also added some other code that might be helpful.

Here is the model:

class Photo(models.Model):
    user = models.ForeignKey(User)
    location = models.ForeignKey(Location)
    title = models.CharField(max_length=30, blank=True, null=True)
    desc = models.CharField(max_length=150, blank=True, null=True, verbose_name='Description')
    created_on = models.DateTimeField(auto_now_add=True)
    photo = models.ImageField(upload_to='photos/%Y/%m/%d')
    tags = TaggableManager(blank=True)


    def __unicode__(self):
        return unicode(self.photo)

and here is the form (using crispy forms):

class PhotoForm(ModelForm):
class Meta:
    model = Photo
    #fields = ['title', 'desc', 'photo', 'tags']

def __init__(self, *args, **kwargs):
    super(PhotoForm, self).__init__(*args, **kwargs)
    self.helper = FormHelper()
    self.helper.form_method = 'post'
    self.helper.layout = Layout(
        Field('title', placeholder="Name it"),
        Field('desc', placeholder="A brief description"),
        Field('photo'),
        Field('tags', placeholder="Optional = Add tags like this Hiking, Reservations, Sight-seeing"),
    )

    self.helper.add_input(Submit('submit_photo', 'Add Photo'))

If I rewrite the view to this:

    if 'submit_photo' in request.POST:
    photo = PhotoForm(request.POST, request.FILES)
    new_photo = photo.save(commit=False)
    new_photo.campground = campground
    new_photo.user = request.user
    new_photo.save()
    photo.save_m2m()  # REQUIRED TO SAVE TAGS

I get the following traceback when I try to upload:

Traceback:
File "/home/bobby/.virtualenvs/campthat3/lib/python2.7/site-            packages/django/core/handlers/base.py" in get_response
115.                         response = callback(request, *callback_args,    **callback_kwargs)
File "/home/bobby/django/campthat3/cg_profiles/views.py" in cg_profile
17.         new_photo = photo.save(commit=False)
File "/home/bobby/.virtualenvs/campthat3/lib/python2.7/site-   packages/django/forms/models.py" in save
370.                              fail_message, commit, construct=False)
File "/home/bobby/.virtualenvs/campthat3/lib/python2.7/site-  packages/django/forms/models.py" in save_instance
75.                          " validate." % (opts.object_name, fail_message))

Exception Type: ValueError at /michigan/bay-view/
Exception Value: The Photo could not be created because the data didn't validate.
Was it helpful?

Solution

From your comment :

I don't get the error page thrown when i have the "if, else" in the view, because it just goes to the "else" and prints the "location required" error in console instead of the whole traceback

The form is not valid, so you cannot save it, even with commit=False. The errors in form might be due to excluded fields from a model, in that case you should not put those fields in the form.

You can either use exclude or fields attribute in meta class:

class PhotoForm(ModelForm):
    class Meta:
        model = Photo
        exclude = ['location', 'user']
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top