I have an Date field that is correctly initiated with an initial value when creating an object, but the existing value is not persisted when editing.
After long time, I found out that I had to format the time correctly, to initiate the form correctly - therefore im inputting the date the same way via if an instance is present.
# forms.py
class ButikkenBookingForm(forms.ModelForm):
class Meta:
model = models.ButikkenBooking
fields =[
"item",
"team",
"team_contact",
"start",
"start_time",
"quantity",
"unit",
"for_meal",
"remarks",
]
widgets = {
"item": forms.Select(attrs={"class": "form-control"}),
"team": forms.Select(attrs={"class": "form-control"}),
"team_contact": forms.Select(attrs={"class": "form-control"}),
"start": forms.DateInput(attrs={"class": "form-control", "type": "date"}),
"start_time": forms.TimeInput(attrs={"class": "form-control", "type": "time"}),
"quantity": forms.NumberInput(attrs={"class": "form-control"}),
"unit": forms.TextInput(attrs={"class": "form-control"}),
"for_meal": forms.Select(attrs={"class": "form-control"}),
"remarks": forms.Textarea(attrs={"class": "form-control"}),
}
labels = {
"item": "Vare",
"team": "Team",
"team_contact": "Kontaktperson",
"start": "Startdato",
"start_time": "Starttidspunkt",
"quantity": "Antal",
"unit": "Enhed",
"for_meal": "Måltid",
"remarks": "Bemærkninger",
}
def save(self, commit=True):
instance = super().save(commit=False)
instance.status = "Pending"
if commit:
instance.save()
return instance
def __init__(self, *args, user=None, **kwargs):
super(ButikkenBookingForm, self).__init__(*args, **kwargs)
self.fields["item"].queryset = ButikkenItem.objects.all()
self.fields["team"].queryset = Team.objects.all()
self.fields["team_contact"].queryset = Volunteer.objects.all()
if user:
print("A user exists")
team_membership = TeamMembership.objects.get(member=user)
self.fields["team"].initial = team_membership.team
self.fields["team_contact"].queryset = Volunteer.objects.filter(
teammembership__team=team_membership.team
)
self.fields["team_contact"].initial = user
# Function to get the next event
def get_next_event():
now = timezone.now()
next_event = Event.objects.filter(start_date__gt=now).order_by('start_date').first()
return next_event
# Check if the form is being initialized with an instance
if self.instance and self.instance.pk:
# Use the existing value from the instance
self.fields["start"].initial = self.instance.start.strftime('%Y-%m-%d')
print(self.instance.start.strftime('%Y-%m-%d'))
else:
# Use the next event's start date if no instance or new instance
next_event = get_next_event()
if next_event:
self.fields["start"].initial = next_event.start_date.strftime('%Y-%m-%d')
self.fields["start_time"].initial = time(8, 0) # Set default time to 08:00 AM
I can see via the print statement in the terminal, that I get the right date format
## output from the terminal:
2024-10-22
[27/Aug/2024 22:40:11] "GET /Butikken/Butikken/ButikkenBooking/update/291/ HTTP/1.1" 200 44791
furthermore I add the template for reference:
{% extends "base.html" %}
{% load static %}
{% load bootstrap_icons %}
{% block content %}
<br>
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="{% url 'index' %}">Hjem</a></li>
<li class="breadcrumb-item"><a href="{% url 'Butikken_ButikkenBooking_list' %}">Butikken bookinger</a></li>
<li class="breadcrumb-item active" aria-current="page">Ny booking </li>
</ol>
</nav>
<br>
<h1 class="display-3" >Ny butikken booking</h1>
{% if user.events.first.deadline_mad %}
<p>Deadline for butikken bestillinger: <mark> {{user.events.first.deadline_mad}} </mark>.</p>
{% endif %}
<form id="form" role="form" method="post">
{% csrf_token %}
{{ form.errors }}
</br>
<div class="form-group row">
<label class="col-sm-2 col-form-label" for="{{ form.item.id_for_label }}">{{ form.item.label }}</label>
<div class="col-sm-10">
<div class="input-group">
{{ form.item }}
</div>
</div>
</div>
</br>
<div class="form-group row">
<label class="col-sm-2 col-form-label" for="{{ form.quantity.id_for_label }}">{{ form.quantity.label }}</label>
<div class="col-sm-10">
<div class="input-group">
{{ form.quantity }}
<span class="input-group-text" id="unit-text">Mængde til 2 personer</span>
</div>
</div>
</div>
</br>
<div class="form-group row">
<label class="col-sm-2 col-form-label" for="{{ form.unit.id_for_label }}">{{ form.unit.label }}</label>
<div class="col-sm-10">
<div class="input-group">
{{ form.unit }}
<span class="input-group-text" id="unit-text">Enhed</span>
</div>
</div>
</div>
</br>
<div class="form-group row">
<label class="col-sm-2 col-form-label" for="{{ form.for_meal.id_for_label }}">{{ form.for_meal.label }}</label>
<div class="col-sm-10">
{{ form.for_meal }}
</div>
</div>
</br>
<div class="form-group row">
<label class="col-sm-2 col-form-label" for="{{ form.team.id_for_label }}">{{ form.team.label }}</label>
<div class="col-sm-10">
{{ form.team }}
</div>
</div>
</br>
<div class="form-group row">
<label class="col-sm-2 col-form-label" for="{{ form.team_contact.id_for_label }}">{{ form.team_contact.label }}</label>
<div class="col-sm-10">
{{ form.team_contact }}
</div>
</div>
</br>
<div class="form-group row">
<label class="col-sm-2 col-form-label" for="{{ form.start.id_for_label }}">{{ form.start.label }}</label>
<div class="col-sm-10">
{{ form.start }}
</div>
</div>
</br>
<div class="form-group row">
<label class="col-sm-2 col-form-label" for="start_time">Start Tid: </label>
<div class="col-sm-10">
<input class="form-control" id="start_time" type="time" name="start_time" value="{{ form.start_time.value }}">
</div>
</div>
</br>
<div class="form-group row">
<label class="col-sm-2 col-form-label" for="{{ form.remarks.id_for_label }}">{{ form.remarks.label }}</label>
<div class="col-sm-10">
{{ form.remarks }}
</div>
</div>
<br>
<div class="form-group row">
<div class="col-sm-10">
<input type="submit" value="Gem" class="btn btn-primary">
</div>
</div>
</form>
{% endblock %}
And the view:
class ButikkenBookingCreateView(generic.CreateView):
model = models.ButikkenBooking
form_class = forms.ButikkenBookingForm
@method_decorator(login_required)
def dispatch(self, request, *args, **kwargs):
event = Event.objects.filter(is_active=True).first()
if event and event.deadline_mad < timezone.now().date():
messages.error(request, 'Deadline for booking overskredet')
return redirect('Butikken_ButikkenBooking_list') # replace with the name of your list view url
return super().dispatch(request, *args, **kwargs)
def get_form_kwargs(self):
kwargs = super().get_form_kwargs()
kwargs['user'] = self.request.user
return kwargs
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
butikken_items = models.ButikkenItem.objects.all()
context['butikken_items'] = butikken_items
return context
class ButikkenBookingUpdateView(UpdateView):
model = models.ButikkenBooking
form_class = forms.ButikkenBookingForm
pk_url_kwarg = "pk"
@method_decorator(login_required)
def dispatch(self, request, *args, **kwargs):
event = Event.objects.filter(is_active=True).first()
if event and event.deadline_mad < timezone.now().date():
messages.error(request, 'Deadline for booking overskredet')
return redirect('Butikken_ButikkenBooking_list') # replace with the name of your list view url
return super().dispatch(request, *args, **kwargs)
def get_form_kwargs(self):
kwargs = super().get_form_kwargs()
kwargs['user'] = self.request.user
return kwargs
And the model:
class ButikkenBooking(models.Model):
# Relationships
team = models.ForeignKey("organization.Team", on_delete=models.CASCADE)
item = models.ForeignKey("Butikken.ButikkenItem", on_delete=models.CASCADE)
team_contact = models.ForeignKey("organization.Volunteer", on_delete=models.CASCADE)
# Fields
STATUS_CHOICES = (
('Pending', 'Pending'),
('Approved', 'Approved'),
('Rejected', 'Rejected'),
('Udleveret', 'Udleveret'),
)
status = models.CharField(max_length=10, choices=STATUS_CHOICES, default='Pending')
start = models.DateField(verbose_name='Start')
start_time = models.TimeField(verbose_name='Start_time')
quantity = models.DecimalField(max_digits=10, decimal_places=2)
unit = models.CharField(max_length=100) # Blank allows for an empty value
created = models.DateTimeField(auto_now_add=True, editable=False)
last_updated = models.DateTimeField(auto_now=True, editable=False)
remarks = models.TextField(blank=True) # Blank allows for an empty value
remarks_internal = models.TextField(blank=True) # Blank allows for an empty value
# Fields
TYPE_CHOICES = (
('Aktivitet', 'Aktivitet'),
('Morgenmad', 'Morgenmad'),
('Frokost', 'Frokost'),
('Aftensmad', 'Aftensmad'),
)
for_meal = models.CharField(max_length=10, choices=TYPE_CHOICES, default='Pending')
class Meta:
verbose_name = "Butiksbestilling"
verbose_name_plural = "Butiksbestillinger"
pass
def __str__(self):
return str(self.pk)
def get_absolute_url(self):
return reverse("Butikken_ButikkenBooking_detail", args=(self.pk,))
def get_update_url(self):
return reverse("Butikken_ButikkenBooking_update", args=(self.pk,))