I have a model / Form / view for a request that works well, but when I want to update a request all the fields are loaded except the due_date field (with a date widget) witch remains empty. If I don’t pay attention I validate and the due_date become None. I would like it to load the date that was saved during creation by default and then I modify it or not. Here is the code.
Model
class Request(models.Model):
thematic = models.ForeignKey(
Thematic,
on_delete=models.SET_NULL,
null=True,
blank=True,
verbose_name="Thématique",
)
context = models.ForeignKey(
Context,
on_delete=models.SET_NULL,
null=True,
blank=True,
verbose_name="Contexte",
)
technical_element = models.CharField(
max_length=255, verbose_name="Élément technique", blank=True, null=True
)
due_date = models.DateField(verbose_name="Date d'échéance", blank=True, null=True)
def __str__(self):
return self.context
class Meta:
verbose_name = "Request"
verbose_name_plural = "Requests"
Forms
class RequestForm(forms.ModelForm):
new_thematic = forms.CharField(
max_length=255, required=False, label="New Thematic"
)
new_context = forms.CharField(
max_length=255, required=False, label="New Context"
)
due_date = forms.DateField(
widget=forms.DateInput(attrs={"type": "date"}),
required=False,
)
class Meta:
model = Demande
fields = "__all__"
widgets = {
"thematic": forms.Select(attrs={"class": "form-control"}),
"context": forms.Select(attrs={"class": "form-control"}),
"technical_element": forms.TextInput(attrs={"class": "form-control"}),
"due_date": forms.DateInput(
attrs={"class": "form-control", "type": "date"}
),
}
def __init__(self, *args, **kwargs):
super(DemandeForm, self).__init__(*args, **kwargs)
if "instance" in kwargs:
instance = kwargs["instance"]
if instance.due_date:
self.fields["due_date"].initial = instance.due_date
self.fields["thematic"].queryset = Thematic.objects.all()
self.fields["context"].queryset = Context.objects.all()
def save(self, commit=True):
instance = super(DemandeForm, self).save(commit=False)
new_thematic_name = self.cleaned_data.get("new_thematic")
new_context_description = self.cleaned_data.get("new_context")
if new_thematic_name:
thematic, created = Thematic.objects.get_or_create(name=new_thematic_name)
instance.thematic = thematic
if new_context_description:
context, created = Context.objects.get_or_create(
description=new_context_description
)
instance.context = context
if commit:
instance.save()
return instance
Views
class UpdateRequestView(View):
def get(self, request, pk):
request_instance = get_object_or_404(Request, pk=pk)
request_form = RequestForm(instance=request_instance)
return render(
request,
"operation/update_request_form.html",
{
"request_form": demande_form,
"request_instance": request_instance,
"title": f"Modify the request {request_instance.context}",
},
)
def post(self, request, pk):
request_instance = get_object_or_404(Request, pk=pk)
request_form = RequestForm(request.POST, instance=request_instance)
if request_form.is_valid():
instance = request_form.save(commit=False)
due_date = request_form.cleaned_data.get("due_date")
if due_date:
instance.due_date = due_date
instance.save()
messages.success(request, "The request was successfully updated.")
return redirect(reverse("drequest_detail", args=[instance.id]))
else:
for field, errors in request_form.errors.items():
for error in errors:
messages.error(request, f"Error {field}: {error}")
return render(
request,
"operation/update_request_form.html",
{
"request_form": demande_form,
"request_instance": request_instance,
"title": f"Modify the request {request_instance.context}",
},
)
In the POST part I have already tried something to display the value of due_date but it does not work.
I tried the init in the form part and another solution in the post part of the view.
Tyrael is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.