My Django models are saved, but the ImageField is not

60 views Asked by At

I am using two classes to abstract the user in my system: the Django default User and my class Documentador. I treat them both as one on the interface side, and for creating a User and Documentador couple i use a Form passed to the template and deal with the data on the View to create and save both the models. My problem is: both models are saved without any errors, but the image in the Documentador class is not.

I tried to create a Documentador model with an image in the Django admin, and it works. I also tested the fields that way: if not form.cleaned_data['foto']: return HttpResponseRedirect('/controle') and i was redirected to that path. I suppose is something with the form or the view, but can't find what.

Form:

class DocumentadorForm(forms.Form):
    foto = forms.ImageField(required=False)
    username = forms.CharField(label="Nome de usuário", max_length="20")
    first_name = forms.CharField(label="Primeiro nome", max_length="30")
    last_name = forms.CharField(label="Sobrenome", max_length="30")
    email = forms.EmailField()
    matricula = forms.IntegerField()
    password = forms.CharField(widget=forms.PasswordInput)

my View:

class UsuarioDocumentadorCreate(View):
    def get(self, request, *args, **kwargs):
        return render(request, 'mmrn/controle/crud_documentador/c_documentador.html', {'form':DocumentadorForm()} )
    def post(self, request, *args, **kwargs):
        form = DocumentadorForm(request.POST, request.FILES)
        if form.is_valid():
            f_foto = form.cleaned_data['foto']
            f_username = form.cleaned_data['username']
            f_first_name = form.cleaned_data['first_name']
            f_last_name = form.cleaned_data['last_name']
            f_email = form.cleaned_data['email']
            f_matricula = form.cleaned_data['matricula']
            f_password = form.cleaned_data['password']

            new_user = User(username=f_username, first_name=f_first_name, last_name=f_last_name, email=f_email)
            doc = Documentador(user=new_user, foto=form.cleaned_data['foto'], matricula=f_matricula)

            new_user.save()
            doc.save()
            return HttpResponseRedirect('/controle/documentadores')
        else: return render(request, 'mmrn/controle/crud_documentador/c_documentador.html',{'form':form})

Documentador model:

class Documentador(models.Model):
    user = models.OneToOneField(User, null=True, on_delete=models.CASCADE)
    foto = models.ImageField(blank=True, upload_to="documentadoresfotos/")
    matricula = models.IntegerField(blank=True)

    def __str__(self):
1

There are 1 answers

1
Avagana On BEST ANSWER

The code you've posted seems reasonable for saving a User and Documentador instance along with an image. Since the Documentador model is being saved successfully in the admin, but not through the form in your view, there might be an issue with the way the form is handling file uploads.

Here are a few things you can check:

  1. HTML Form Attributes: Ensure that your HTML form tag includes the enctype="multipart/form-data" attribute. This attribute is required for forms that have a file upload field.

    <form method="post" enctype="multipart/form-data">
    <!-- Your form fields go here -->
    </form>
    
  2. Check Form Validation Errors: In your view's post method, after validating the form, you can print the form's errors to the console to see if there are any issues related to file uploads.

    if form.is_valid():
    # Your existing code here
    else:
    print(form.errors)
    return render(request, 'mmrn/controle/crud_documentador/c_documentador.html', {'form': form})
    

    This will give you more information about any form validation errors.

  3. Check if Files Are Being Sent: Use request.FILES to check if files are being sent with the request. Add a print statement to check if the file data is present.

    print(request.FILES)
    
  4. Update HTML Form for File Upload: Ensure that the form in your HTML file has the correct enctype attribute and the foto input field is of type file.

    <form method="post" enctype="multipart/form-data">
    {% csrf_token %}
    {{ form }}
    <button type="submit">Submit</button>
    </form>
    
  5. Check File Permissions: Ensure that the directory specified in upload_to="documentadoresfotos/" has the necessary write permissions for the Django server.

By going through these steps, you should be able to identify the issue with the file upload. If the problem persists, you might want to consider using Django's ModelForm for the Documentador model, which can simplify form handling for model instances with file fields.