MattWaters
MattWaters

Reputation: 221

Django Forms - DateInput not populating from instance

I'm trying to set up an edit form for a Django model which includes a DateField. I've set this field as a forms.DateInput in forms.py. This works fine for creating a new instance of the model, but when I try to populate the form with an existing instance the DateInput field remains blank even though all of the other fields are populated correctly.

If I revert to the default TextField input then the data is recalled correctly. I've also tried to set a format in the DateInput widget.

models.py

class Rider(models.Model):
    first_name = models.CharField(max_length=40)
    surname = models.CharField(max_length=40)
    MALE = 'M'
    FEMALE = 'F'
    GENDER_CHOICES = [
        (MALE, 'Male'),
        (FEMALE, 'Female'),
    ]
    gender = models.CharField(max_length=1, choices=GENDER_CHOICES)
    dob = models.DateField("Date of Birth", auto_now = False, auto_now_add = False)
    club = models.CharField(max_length=50,blank=True, null=True)
    bc_number = models.IntegerField("British Cycling Membership Number", blank=True, null=True)
    linked_account = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, default=1)

views.py

def rider_edit(request, pk):
    rider = get_object_or_404(Rider, pk=pk)
    if request.method == "POST":
        form = RiderForm(request.POST, prefix='rider', instance=rider)
        if form.is_valid():
            rider = form.save(commit=False)
            rider.linked_account = request.user
            rider.save()

            return redirect('rider_list')
    else:
        form = RiderForm(prefix='rider', instance=rider)
    return render(request, 'riders/rider_new.html', {'riderform': form})

form.py

from django import forms
from .models import Rider, MedicalInfo


class RiderForm(forms.ModelForm):

    class Meta:
        model = Rider
        fields = ('first_name', 'surname', 'gender', 'dob', 'club', 'bc_number')
        widgets= {
            'dob': forms.DateInput(attrs={'type': 'date'}, format='%d/%m/%Y')
        }

rider_new.html

<h2>New Rider</h2>
    <form method="POST" class="post-form">
        {% csrf_token %}
        {{ riderform.as_p }}
        <button type="submit" class="save btn btn-default">Add Rider</button>
    </form>

The dob field is the only field that doesn't populate correctly from the database, it should show a date in the format dd/mm/YYYY e.g. "10/09/2010". It's actually showing the default "dd/mm/YYYY".

Upvotes: 5

Views: 2312

Answers (2)

Wilmi Vizcaino
Wilmi Vizcaino

Reputation: 71

Similarly. if you are using the DateInput Class, you will need to pass a format when calling the class in the widget. For example:

forms.py

#This is used to provide date widget in model forms
class DateInput(forms.DateInput):
    input_type = 'date'

Now within the form, when you specify the widget, you can pass the format as a key word argument. In my case:

widgets = {
        "start_date": DateInput(format='%Y-%m-%d'),
        "end_date": DateInput(format='%Y-%m-%d')
    }

Upvotes: 0

MattWaters
MattWaters

Reputation: 221

I found a solution to the problem, the date from the database was being returned in "%d/%m/%Y" format but the input on the form was of the "date" type which expects an input in the format "%Y-%m-%d", by changing:

widgets= {
            'dob': forms.DateInput(format=('%d/%m/%Y'), attrs={'class':'form-control', 'placeholder':'Select Date','type': 'date'})
        }

to:

widgets= {
            'dob': forms.DateInput(format=('%Y-%m-%d'), attrs={'class':'form-control', 'placeholder':'Select Date','type': 'date'})
        }

Therefore, the generated HTML form changed from:

<input type="date" name="rider-dob" value="10/09/2010" class="form-control" placeholder="Select Date" required="" id="id_rider-dob">

to:

<input type="date" name="rider-dob" value="2010-09-10" class="form-control" placeholder="Select Date" required="" id="id_rider-dob">

Upvotes: 17

Related Questions