Issue
I am trying to render a ChoiceField in django template, I do not know if i am doing the right thing but the selected ChoiceField saved in database when form is submitted. Now, how do i get the selected choice(Like Placeholder). If choice field is empty i do not want to see (---) I want a placeholder (Choose your gender). And when a gender is selected, i want the placeholder to be replaced by the value(Male instead of Choose your gender).
Views.py:
def profile_edit(request):
updateform = UpdateUserForm(request.POST, instance=request.user)
profileeditform = ProfileEditForm(request.POST, instance=request.user.profile)
if request.method == 'POST':
if updateform.is_valid() and profileeditform.is_valid():
updateform.save()
profileeditform.save()
messages.info(request, 'Your profile was successfully updated!')
return redirect('site:profile-edit')
else:
updateform = UpdateUserForm(instance=request.user)
profileeditform = ProfileEditForm(instance=request.user.profile)
#I am trying to get the value of gender choices field of user and pass it value to template, but i am getting an error "invalid literal for int() with base 10: 'male'"
gender = Profile.objects.filter(user=request.user.profile.gender)
context = {
'updateform': updateform,
'profileeditform': profileeditform,
'gender': gender,
}
return render(...)
Model.py:
GENDER = (
('male', 'male'),
('female', 'female'),
('custom', 'custom'),
('Prefer Not To Say', 'Prefer Not To Say'),
)
class Profile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL,on_delete=models.CASCADE,blank=True,null=True)
gender = models.CharField(max_length=50, choices=GENDER, verbose_name="gender", blank=True)
Forms.py:
class ProfileEditForm(forms.ModelForm):
class Meta:
model = Profile
fields = (
'bio',
'phone',
'gender',
)
Template.html:
<select class="custom-select md-form" name="gender" id="id_gender">
{% for male,female in profileeditform.fields.gender.choices %}
<option value="{{ male }}" {% if profileeditform.fields.gender.value == male %} selected=""{% endif %}>{{ female }}</option>
{% endfor %}
</select>
Solution
The last paragraph of the documentation on model field choices explains how to achieve this:
..add a tuple to choices containing None; e.g. (None, 'Your String For Display').
So in your models.py:
GENDER = (
(None, 'Choose your gender'),
('male', 'male'),
('female', 'female'),
('custom', 'custom'),
('Prefer Not To Say', 'Prefer Not To Say'),
)
You will probably need to change your views.py, because you were binding the forms before checking if the request.method
was 'POST'. The following follows the logic recommended in the docs:
def profile_edit(request):
if request.method == 'POST':
updateform = UpdateUserForm(request.POST, instance=request.user)
profileeditform = ProfileEditForm(request.POST, instance=request.user.profile)
if updateform.is_valid() and profileeditform.is_valid():
updateform.save()
profileeditform.save()
messages.info(request, 'Your profile was successfully updated!')
return redirect('site:profile-edit')
else:
updateform = UpdateUserForm(instance=request.user)
profileeditform = ProfileEditForm(instance=request.user.profile)
context = {
'updateform': updateform,
'profileeditform': profileeditform,
'gender': gender,
}
return render(...)
Update your forms.py and nominate the widget (this is necessary if you want to set class names, etc):
class ProfileEditForm(forms.ModelForm):
class Meta:
model = Profile
fields = (
'bio',
'phone',
'gender',
)
widgets = {
'gender': forms.Select(attrs={'class': 'custom-select md-form'}),
}
Then you should be able to just render the form field in your template:
{{ profileeditform.gender }}
Answered By - MattRowbum
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.