Philip007
Philip007

Reputation: 3230

Django: save model object of a ModelForm

I have a ModelForm:

class UploadForm(forms.ModelForm):  
    class Meta:
        model = Image
        fields = ['image']

which is based on model Image

class Image(models.Model):
    def content_file_name(instance, filename):
        return filename

    name = models.CharField(max_length=50)
    image = models.ImageField(upload_to=content_file_name)
    user = models.ForeignKey(MyUser, related_name='image')  

In views.py, I try to save the image name and user object (from session) along with the uploaded image to database.

    form1 = UploadForm(request.POST, request.FILES)
    if form1.is_valid():
        image = request.FILES['image']  # image is of UploadedFile class
        form1.Meta.model.name = image.name
        form1.Meta.model.user = get_object_or_404(MyUser,username=request.session['user'])
        form1.save()
        return render(request, '16_upload01.html', context)

Problem is only the uploaded image gets saved. Error message in browser:

IntegrityError at /competition-big/big1/upload comp_app_image.user_id may not be NULL

I confirmed this by checking on SQL command:

INSERT INTO "comp_app_image" ("name", "image", "user_id") VALUES ('', 'grey-160-100_1.png', None)


I figure that image name and user are not bounded to form1. But how can I achieve that?


EDIT
After some digging, I know I messed up with above code. Now I changed my code to this:

if form1.is_valid():
        form1.cleaned_data['user'] = get_object_or_404(MyUser, username=request.session['user'])
        form1.save()

But I still get null user_id error.

EDIT 2
Thanks Jacinda. Now I get this cleaner code:

if form1.is_valid():
        form1.cleaned_data['user'] = request.user
        form1.save()

But error null user_id remains.

Upvotes: 1

Views: 316

Answers (2)

Burhan Khalid
Burhan Khalid

Reputation: 174624

If this form can only be accessed by a logged in user, use the login_required decorator, and you should always redirect after a POST. You should also read this section in the ModelForms documentation; which describes how to properly use a model form that has limited fields.

from django.shortcuts import redirect
from django.contrib.auth.decorators import login_required

@login_required
def your_view(request):
  form1 = UploadForm(request.POST, request.FILES)
  if form1.is_valid():
      image = request.FILES['image']  # image is of UploadedFile class
      obj = form1.save(commit=False)
      obj.name = image.name
      obj.user = request.user
      obj.save()
      return redirect('your-view-name')
  else:
      return render(request, 'form.html', {'form': form1})  

Upvotes: 2

Jacinda
Jacinda

Reputation: 5072

I think your issue is probably this line:

form1.Meta.model.user = get_object_or_404(MyUser,username=request.session['user'])

When I try and use your syntax (using the Django default django.contrib.auth) I get a KeyError on 'user'.

What I've always done when I need information about the user associated with a request is this:

username = request.user.username

Reference: https://docs.djangoproject.com/en/dev/ref/request-response/#django.http.HttpRequest.user

Of course, this will only work if your users are required to be logged in to upload images.

Upvotes: 1

Related Questions