my form cannot receive request.files. I have a problem that user profile photo cannot be uploaded. img is sent trough request method properly

Viewed 66

** views.py **

def create_user(request):
    if request.method == 'POST':
        form = UserProfile(request.POST)
        user_photo = PhotoUser(request.FILES,request.POST) #instance=request.user.userphoto
        print(request.FILES) * here i can see my image went trough *
        if form.is_valid():
            form.save()

    else:
        form = UserProfile()
        user_photo = PhotoUser()
    return render(request,'user/user.html',{'form':form,'user_photo':user_photo})

** urls.py**

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', views.exe,name='exe'),
    path('books/', include('books.urls')),
    path('user/', include('user.urls')),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) 

** signals.py**

@receiver(post_save,sender=User)
def create_profile(sender, instance, created, **kwargs):
    if created:
        UserPhoto.objects.create(user=instance)


@receiver(post_save, sender=User)
def save_profile(sender, instance, **kwargs):
    instance.userphoto.save()

** models.py **

class UserPhoto(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    img = models.ImageField(upload_to=image_directory_path,default='avatar.png',blank=True,null=True)


    def __str__(self):
        return self.user.username

** html**

<form method="post" enctype="multipart/form-data" action=".">
    {% csrf_token %}
    {{form}}
    {{user_photo}}
    <input type="file" name="img" accept="image/*" id="id_img">
    <input type="submit" value="Submit">

</form>

forms.py

class PhotoUser(forms.ModelForm):
    class Meta:
        model = UserPhoto
        fields = ['img']
MEDIA_ROOT = (BASE_DIR / 'media')
MEDIA_URL = '/media/'

so everything works ok but users profile images are not getting uploaded.

signals are executed properly and 2 models are conected and my avatar.png is uploaded to every user and user is saved.

if i upload user photo via admin it works properly

1 Answers

Please remove the signal to create a UserPhoto, it will result in the fact that the form and the signal try to create both a UserPhoto, and therefore either one of the two will fail, in this case that will be the PhotoUser form. Furthermore, using Signals, often result in problems, and only in specific cases these are effective.

You can implement a view that will create a UserPhoto that is linked to the logged in user:

# remove the create_profile signal

def create_user(request):
    if request.method == 'POST':
        form = UserProfile(request.POST)
        user_photo = PhotoUser(request.FILES, request.POST) #instance=request.user.userphoto
        if form.is_valid() and user_photo.is_valid():
            user = form.save()
            user_photo.instance.user = user
            user_photo.save()
            return redirect('name-of-some-view')

    else:
        form = UserProfile()
        user_photo = PhotoUser()
    return render(request,'user/user.html',{'form':form,'user_photo':user_photo})

Note: In case of a successful POST request, you should make a redirect [Django-doc] to implement the Post/Redirect/Get pattern [wiki]. This avoids that you make the same POST request when the user refreshes the browser.

Related