Reputation: 155
I have a model:
class Planning (models.Model):
#other fields#
month = models.DateField(default=date.today)
class Meta:
verbose_name_plural = 'Planning'
And I have this model form:
class PlanningForm(forms.ModelForm):
#other fields#
month = forms.DateField(
label='Mês/Ano',
required=True,
widget=forms.SelectDateWidget(
attrs={'type': 'date',
'value': date.today},}),
error_messages={'required': '', },
)
class Meta:
model = Planning
fields = '__all__'
The view:
def new_planning(request):
form = PlanningForm(request.POST)
if form.is_valid():
form.save()
if 'another' in request.POST:
messages.success(request, ('Lançamento salvo com sucesso!'))
return redirect('app:new_planning')
else:
return redirect('app:list_planning')
return render(request, 'app/pages/planning/new_planning.html', context={
'form': form,
})
I'm using SelectDateWidget to show only month/year (I hid the day selector using CSS), like this:
The form is working as intended, but the issue is that I can't set the field to show the current date. When the form is rendered, it always shows the first date of the year.
In the above code, I tried to show the date using the value attribute from HTML. This works perfectly when I use widget=forms.DateInput
but I imagine that the widget is changing the input completely so it doesn't work.
I also tried to add an initial value the same way I did for the model using the line initial=date.today
, but for what i can get, this only works for unbound forms and since my view runs a if form.is_valid():
, that is not the case.
And I did try to set a range for the months, along the lines of this question, but with no luck.
Is there a way to set the current date with this specific widget?
Edit:
I could be completely wrong, but I'm assuming that the date input is converted to an actual date AFTER save. In this widget you can set a list/tuple/dict with the values you want to show. So if it is converting the values to dates after save, it make sense that it doesn't recognize the current date. To test this I added a list and dict with the months and years choice:
class PlanningForm(forms.ModelForm):
MONTHS = {1: ('this'), 2: ('is'), 3: ('text'), }
YEARS = ['and_so_is_this']
month = forms.DateField(
label='Mês/Ano',
required=True,
widget=forms.SelectDateWidget(
months=MONTHS,
years=YEARS,
attrs={'type': 'date', }),
error_messages={'required': '', },
)
And the result:
Upvotes: 2
Views: 1818
Reputation: 551
You should be able to do this by overriding the __init__
method:
from datetime import datetime
class PlanningForm(forms.ModelForm):
# ...
month = forms.DateField(
label="Mês/Ano",
required=True,
widget=forms.SelectDateWidget(attrs={"type": "date"}),
error_messages={
"required": "",
},
)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['month'].initial = datetime.now() # or timezone aware equivalent
# ...
I think there's also an issue with the indentation and parentheses of your month
field declaration
EDIT: It seems that the initial value must be a datetime
object.
EDIT 2: The view and template I've used to test this
View:
class PlanningView(FormView):
form_class = PlanningForm
template_name = "planning/form.html"
Template:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
{{ form }}
</body>
</html>
Upvotes: 3