Problem with Django Forms and models (Enter a valid URL.)

My idea is to get a img from the user using the form (it can be local on her computer) and after the form is sent the system upload it to imgBB. The problem is that the form is not valid, because it says "Enter a valid URL.".

class FeriaForm(forms.ModelForm):
    #... Others fields
    image = forms.URLField(
        label="",
        widget=forms.ClearableFileInput(attrs={'class': 'form-input'})
    )
    class Meta:
        model = JobFair
        fields = [
            'title', 'description', 'start_event_date',
            'end_event_date', 'start_hour', 'end_hour',
            'department', 'city', 'direction',
            'maximum_capacity', 'is_visible',
            'keynote_speaker', 'image'
        ]

This model JobFair

class JobFair(models.Model):
    organizer = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='job_fairs', null=True)
    title = models.CharField(max_length=255)
    description = models.TextField()
    start_event_date = models.DateField()
    end_event_date = models.DateField(null=True)
    department = models.CharField(max_length=255)
    city = models.CharField(max_length=255)
    start_hour = models.TimeField(auto_now=False, auto_now_add=False)
    end_hour = models.TimeField(auto_now=False, auto_now_add=False, null=True)
    maximum_capacity = models.IntegerField(null=True)
    number_of_registered = models.IntegerField(default=0, null=True)
    is_visible = models.BooleanField(default=True)
    direction = models.CharField(max_length=255)
    keynote_speaker = models.CharField(max_length=255)
    image = models.URLField(blank=True, null=True)

and this view where I used the form.

def add_fair_view(request):
    if request.method == 'POST':
        form = FeriaForm(request.POST, request.FILES)  # Manejar datos y archivos
        if form.is_valid():
            image_file = request.FILES.get('image')  # Obtener el archivo de la imagen
            
            # Subir el archivo a ImgBB
            try:
                response = requests.post(
                    IMGBB_API_URL,
                    data={'key': config('IMGBB_API_KEY')},
                    files={
                        'image': (image_file.name, image_file.file, image_file.content_type)
                    }
                )
                response_data = response.json()
                
                if response.status_code == 200:
                    # Obtener la URL de la imagen subida
                    img_url = response_data['data']['url']
                    
                    # Guardar la feria en la base de datos
                    fair = form.save(commit=False)  # No guardar todavía
                    fair.organizer = request.user
                    fair.image = img_url  # Asignar la URL
                    fair.save()  # Guardar en la base de datos

                    return redirect('view_fairs')
                else:
                    # Error al subir a ImgBB
                    form.add_error('image', f"Error al subir la imagen: {response_data.get('error', {}).get('message', 'Desconocido')}")
            
            except requests.RequestException as e:
                # Error al realizar la solicitud a ImgBB
                form.add_error('image', f"Error al subir la imagen: {str(e)}")
    else:
        form = FeriaForm()
    
    return render(request, 'addfair.html', {'form': form})

I have try it changing the image as image = forms.ImageField(...), but when I did it says "No file was summited/ check the enctype". The HTML form have the enctype configure. I really don't know what to do. I appreciate any kind of help.

The problem is that you're using forms.URLField, which expects a URL, for an image upload. Instead, you should use forms.ImageField to properly handle file uploads.

image = forms.ImageField(
    label="",
    widget=forms.ClearableFileInput(attrs={'class': 'form-input'})
)

By making this adjustment, your form will be able to handle image uploads correctly. I hope this helps! Thank you, and good luck! ✨

Вернуться на верх