1

I am facing a strange problem while implementing ChoiceField and UpdateView in django. I have made a small clip showing the problem that I am facing. Please watch it with subtitles/cc enabled. It will give an idea about the problem I am facing. https://youtu.be/M36TnlJvrZs. The problem goes like this.....

During CreateView, I set the 'gender' ChoiceField as 'Female'. But in UpdateView it pre-populates the 'gender' ChoiceField as Male.

However, The ListView renders the 'gender' field properly as 'Female'.

And strangely, the django admin panel, displays no value at all for the 'gender' field.

Here are all the codes:

models.py:

from django.db import models
from django.core.urlresolvers import reverse

gender_choices = (('Male', 'Male'), ('Female', 'Female'))

class Birth(models.Model):
    full_name = models.CharField(max_length = 100)    
    gender = models.CharField(max_length=6, choices=gender_choices)
    date_of_birth = models.DateField()
    place_of_birth = models.CharField(max_length = 50)
    mother_name = models.CharField(max_length = 50)
    father_name = models.CharField(max_length = 50)
    address_at_time_of_birth = models.TextField(max_length = 500)
    permanent_address = models.TextField(max_length = 500)
    registration_no = models.CharField(max_length = 50)
    remarks = models.CharField(max_length = 200)    
    registration_date = models.DateField()
    issue_date = models.DateField()

    def get_absolute_url(self):
        return reverse('birth:birth_update', kwargs={'pk':self.pk})
        #return reverse('birth:birth_home')

    def __str__(self):
        return self.full_name

forms.py:

from django import forms
from .models import *    

class BirthForm(forms.ModelForm):
        full_name = forms.CharField()
        gender = forms.ChoiceField(choices = gender_choices, widget=forms.Select())
        date_of_birth = forms.DateField(widget = forms.DateInput(attrs = {'placeholder':'DD/MM/YYYY'}))
        place_of_birth = forms.CharField()
        mother_name = forms.CharField()
        father_name = forms.CharField()
        address_at_time_of_birth = forms.CharField(widget = forms.Textarea())
        permanent_address = forms.CharField(widget = forms.Textarea())
        registration_no = forms.CharField(required = False)
        registration_date = forms.DateField(required = False, widget = forms.DateInput(attrs = {'placeholder':'DD/MM/YYYY'}))
        remarks = forms.CharField(required = False)
        issue_date = forms.DateField(required = False, widget = forms.DateInput(attrs = {'placeholder':'DD/MM/YYYY'}))


        class Meta:
            model = Birth
            fields = '__all__'

views.py:

from django.views.generic import ListView, CreateView, UpdateView
from .models import *
from .forms import *
from datetime import date


class BirthHome(ListView):
    template_name = 'birth/birth_home.html'
    model = Birth
    context_object_name = 'birth_objects'
    paginate_by = 20

    def get_queryset(self):
        return Birth.objects.all().order_by('-id')


class NewBirth(CreateView):
    model = Birth
    form_class = BirthForm
    #fields = '__all__' 
    template_name = 'birth/birth_add.html'


    def form_valid(self, form):
        obj = form.save(commit = False)
        if not obj.registration_date:
            obj.registration_date = date.today()
        if not obj.issue_date:
            obj.issue_date = date.today()
        if not (date(1900, 1, 1) <= obj.date_of_birth <= date.today()):
            form.add_error('date_of_birth', 'Please enter a valid date')
            return super(NewBirth, self).form_invalid(form)
        obj.full_name = obj.full_name.upper()
        obj.gender = obj.gender.upper()
        obj.place_of_birth = obj.place_of_birth.upper()
        obj.mother_name = obj.mother_name.upper()
        obj.father_name = obj.father_name.upper()
        obj.address_at_time_of_birth = obj.address_at_time_of_birth.upper()
        obj.permanent_address = obj.permanent_address.upper()
        if obj.remarks:
            obj.remarks = obj.remarks.upper()
        self.object = form.save()
        return super(NewBirth, self).form_valid(form)


class BirthUpdate(UpdateView):
    model = Birth
    form_class = BirthForm
    template_name = 'birth/birth_update.html'

    def form_valid(self, form):
        obj = form.save(commit = False)
        if not obj.registration_date:
            obj.registration_date = date.today()
        if not obj.issue_date:
            obj.issue_date = date.today()
        if not (date(1900, 1, 1) <= obj.date_of_birth <= date.today()):
            form.add_error('date_of_birth', 'Please enter a valid date')
            return super(BirthUpdate, self).form_invalid(form)
        obj.full_name = obj.full_name.upper()
        obj.gender = obj.gender.upper()
        obj.place_of_birth = obj.place_of_birth.upper()
        obj.mother_name = obj.mother_name.upper()
        obj.father_name = obj.father_name.upper()
        obj.address_at_time_of_birth = obj.address_at_time_of_birth.upper()
        obj.permanent_address = obj.permanent_address.upper()
        if obj.remarks:
            obj.remarks = obj.remarks.upper()
        self.object = form.save()
        return super(BirthUpdate, self).form_valid(form)

I searched a lot and experimented a lot as well, but to no avail. Seriously need help. Also if this approach is not correct, what should be the correct working approach??

Regolith
  • 2,944
  • 9
  • 33
  • 50
dhruvparekh12
  • 92
  • 1
  • 13

1 Answers1

0

Solved!

So after lots of experimenting, I realized what the problem was!! It was in models.py file:

Since, I was converting all my inputs to uppercase, the 'choices' tuple also needed to have the values in uppercase. Initially the gender_choices tuple read like this:

gender_choices = (('Male', 'Male'), ('Female', 'Female'))

And in my views, I was making the gender as uppercase, thus causing mis-match in the declared tuple data and form data.

So, I changed the tuple to this:

gender_choices = (('MALE', 'MALE'), ('FEMALE', 'FEMALE'))

Works like a Charm!! Cheers.... And thanx for all the help and suggestions. Any feedback is always welcome :)

dhruvparekh12
  • 92
  • 1
  • 13