0

So, I am trying to create a Profile Update Form. My problem is that my form updates every field except profile_pic and profile_bio. However, I have updated them successfully directly through the PostgreSQL admin. Most of the answers I found for this problem were to include enctype="multipart/form-data" in the template tag, but I have it already. How do you think I can resolve this issue?

This is the Profile Model

class Profile(models.Model):
    user = models.OneToOneField(User, null=True, on_delete=models.CASCADE)
    profile_pic = models.ImageField(null=True, blank=True, upload_to='images/profile/')
    profile_bio = models.TextField(null=True, blank=True)

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

This is the form for Profile Update

class EditProfileForm(forms.ModelForm):
    class Meta:
        model = Profile
        fields = ['first_name', 'last_name', 'username', 'email', 'profile_bio', 'profile_pic']

    first_name = forms.CharField(max_length=100, widget=forms.TextInput(attrs={'class': 'form-control'}))
    last_name = forms.CharField(max_length=100, widget=forms.TextInput(attrs={'class': 'form-control'}))
    username = forms.CharField(max_length=100, widget=forms.TextInput(attrs={'class': 'form-control'}))
    email = forms.EmailField(widget=forms.EmailInput(attrs={'class': 'form-control'}))
    profile_bio = forms.CharField(widget=forms.Textarea(attrs={'class': 'form-control'}))

    password = None

This is the View that is supposed to update the profile, it updates all the field successfully except profile_bio and profile_pic

class UserEditView(UpdateView):
    form_class = EditProfileForm
    template_name = 'registration/edit_profile.html'
    success_url = reverse_lazy('home')

    def get_object(self):
        return self.request.user

The registration/edit_profile.html Template

{% extends 'base.html' %}

{% block title %}
    Edit Profile
{% endblock %}

{%  block content %}
    <div class="d-flex justify-content-center">
        <div class="card" style="width: 30rem;">
            <div class="card-body">
                <h1 class="text-center mb-4">Edit Profile</h1>
                <div>
                    <form class="form-group" method="POST" enctype="multipart/form-data">
                        {% csrf_token %}
                            {% for field in form %}
                                <p>
                                    {{ field.label }}
                                    {{ field }}
                                </p>
                            {% endfor %}
                        <button class="btn btn-primary" type="submit">Update</button>
                        <a class="btn btn-danger" href="{% url 'show_profile' user.profile.id %}">Cancel</a>
                    </form>
                </div>
            </div>
        </div>
    </div>
{% endblock %}

settings.py

STATIC_URL = '/static/'
MEDIA_URL = '/media/'

MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'static'),
]
  • The model `Profile` is not the same as the user model (You write `return self.request.user` in `get_object`). You are trying to update two different model instances at the same time. – Abdul Aziz Barkat Mar 26 '21 at 14:43
  • @AbdulAzizBarkat thank you! I fixed it with your help, but not perfectly. I made it return self.request.user.profile, but this way it does not allow to update user fields now (name, username, email and etc.) Do you know how can I make it update two object instances: User and Profile? – Amirkhan Alpyspayev Mar 26 '21 at 16:10
  • @AmirkhanAlpyspayev Useful ans.: https://stackoverflow.com/q/18122096/14131913 – Pradip Kachhadiya Mar 27 '21 at 05:47

0 Answers0