I cannot get the default User model or my created Agent model to update. Below is my admin.py, forms.py, models.py, urls.py, views.py, and my edit_profile.html. I know it must be silly, but I've got three good days working on this.
The HTML page tries to edit both the EditProfileForm and the MoreInfoForm. The EditProfileForm uses the built-in User model, while the MoreInfoForm is my model that extends the built-in User model. As a note, the MoreInfoForm also contains an Image that I want to be able to update.
When I submit the form, I get a POST request, but when I view the profile, it doesn't contain any changes.
admin.py:
class AgentInline(admin.StackedInline):
model = Agent
can_delete = False
verbose_name_plural = 'agent'
class UserAdmin(BaseUserAdmin):
inlines = (AgentInline,)
admin.site.unregister(User)
admin.site.register(User, UserAdmin)
forms.py:
class RegisterUserForm(UserCreationForm):
email = forms.EmailField(widget=forms.EmailInput(attrs={'class': 'form-control'}))
first_name = forms.CharField(max_length=50,
widget=forms.TextInput(attrs={'class': 'form-control'}))
last_name = forms.CharField(max_length=50,
widget=forms.TextInput(attrs={'class': 'form-control'}))
class Meta:
model = User
fields = ('username',
'first_name',
'last_name',
'email',
'password1',
'password2',)
def __init__(self, *args, **kwargs):
super(RegisterUserForm, self).__init__(*args, **kwargs)
self.fields['username'].widget.attrs['class'] = 'form-control'
self.fields['password1'].widget.attrs['class'] = 'form-control'
self.fields['password2'].widget.attrs['class'] = 'form-control'
class MoreInfoForm(forms.ModelForm):
agent_phone_num = forms.CharField(max_length=10,
required=True,
help_text='Enter a 10 digit # without spaces or dashes',
widget=forms.TextInput(
attrs={'class': 'form-control'}))
agent_mls = forms.CharField(max_length=6,
required=True,
help_text='Enter your 6 digit MLS #',
widget=forms.TextInput(
attrs={'class': 'form-control'}))
headshot = forms.ImageField(required=False,
error_messages={'invalid': 'Image files only'},
widget=forms.FileInput(attrs={'class': 'form-control'}))
class Meta:
model = Agent
fields = ('agent_phone_num',
'agent_mls',
'headshot',)
class EditProfileForm(UserChangeForm):
email = forms.EmailField(widget=forms.EmailInput(attrs={'class': 'form-control'}))
first_name = forms.CharField(max_length=50,
widget=forms.TextInput(attrs={'class': 'form-control'}))
last_name = forms.CharField(max_length=50,
widget=forms.TextInput(attrs={'class': 'form-control'}))
class Meta:
model = User
fields = ('first_name',
'last_name',
'email',
'password',)
def __init__(self, *args, **kwargs):
super(EditProfileForm, self).__init__(*args, **kwargs)
del self.fields['password']
models.py:
class Agent(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
agent_phone_num = models.CharField(blank=False, max_length=10, default=None)
agent_mls = models.CharField(blank=False, max_length=6, default=None)
headshot = models.ImageField(upload_to='agents', blank=True)
def formatted_phone(self):
phone_string = f'{self.agent_phone_num}'
return ('1-' +
phone_string[:3] + '-' +
phone_string[3:6] + '-' +
phone_string[6:])
def __str__(self):
return self.user.username + self.formatted_phone()
urls.py:
urlpatterns = [
path('login', views.login_user, name='login', ),
path('logout', views.logout_user, name='logout', ),
path('register', views.register_user, name='register', ),
path('profile', views.view_profile, name='profile', ),
path('profile/edit/', views.edit_profile, name='edit_profile', ),
# TODO user password reset page
path('reset_password/',
auth_views.PasswordResetView.as_view(),
name='reset_password'),
path('reset_password_sent',
auth_views.PasswordResetDoneView.as_view(),
name='password_reset_done'),
path('reset/<uidb64>/<token>/',
auth_views.PasswordResetConfirmView.as_view(),
name='password_reset_confirm'),
path('reset_password_complete/',
auth_views.PasswordResetCompleteView.as_view(),
name='password_reset_complete'),
]
views.py:
def login_user(request):
if request.method == 'POST':
username = request.POST['username']
password = request.POST['password']
user = authenticate(request, username=username, password=password)
if user is not None:
login(request, user)
return redirect('index')
else:
messages.success(request, 'There Was An Error Logging In, Try Again...')
return redirect('login')
else:
return render(request, 'authenticate/login.html', {
})
def logout_user(request):
logout(request)
messages.success(request, 'You Were Logged Out!')
return redirect('index')
def register_user(request):
if request.method == 'POST':
form = RegisterUserForm(request.POST)
more_form = MoreInfoForm(request.POST, request.FILES)
if form.is_valid() and more_form.is_valid():
user = form.save()
more = more_form.save(commit=False)
more.user = user
more.save()
username = form.cleaned_data['username']
password = form.cleaned_data['password1']
user = authenticate(username=username, password=password)
login(request, user)
messages.success(request, 'Registration Successful!')
return redirect('index')
else:
form = RegisterUserForm()
more_form = MoreInfoForm(request.POST)
return render(request, 'authenticate/register_user.html', {
'form': form,
'more_form': more_form,
})
def view_profile(request):
return render(request, 'authenticate/profile.html', {
'user': request.user,
})
def edit_profile(request):
user_profile = get_object_or_404(Agent, user=request.user)
if request.method == 'POST':
form = EditProfileForm(request.POST, instance=request.user)
more_form = MoreInfoForm(request.POST, request.FILES, instance=user_profile)
if form.is_valid() and more_form.is_valid():
form.save()
more_form.save()
messages.success(request, 'Your profile has been updated.')
return redirect('edit_profile')
else:
form = EditProfileForm(instance=request.user)
more_form = MoreInfoForm(instance=user_profile)
return render(request, 'authenticate/edit_profile.html', {
'form': form,
'more_form': more_form,
'user_profile': user_profile,
})
edit_profile.html:
<div class="container"
style="min-height: 100vh">
{% if user.is_authenticated %}
<h1 class="h1 text-center mt-3 text-capitalize">{{ user.first_name }}'s Profile</h1>
<div class="">
<img src="{{ user.agent.headshot.url }}"
alt="Profile Picture"
class=""
height="300"
width="">
</div>
<form action="{% url 'edit_profile' %}"
method="POST"
enctype="multipart/form-data">
{% csrf_token %}
{{ form.first_name }}
{{ form.last_name }}
{{ form.email }}
{{ more_form.agent_phone_num }}
<div class="form-group col-md-6">
<label for="">Profile Picture</label>
{{ more_form.headshot }}
</div>
<input type="submit"
class="btn btn-secondary"
value="Save">
{#<button class="btn btn-secondary"#}
{# type="submit">Save#}
{#</button>#}
</form>
{% else %}
<h1 class="h1 text-center mt-3">You must be logged in to view this page</h1>
<div class="text-center m-3">
<a href="{% url 'login' %}"
class="text-decoration-none">
<button type="button"
class="btn btn-light pl-5 pr-5">Login
</button>
</a>
</div>
{% endif %}
</div>