I changed UpdateView
so that it can handle create requests as well if pk=0
:
class ObjectView(UpdateView):
def get_object(self, queryset=None):
if self.kwargs.get(self.pk_url_kwarg) == 0:
return None
return super().get_object(queryset)
def form_valid(self, form):
if self.request.htmx:
return self.render_to_response(self.get_context_data(form=form))
return redirect(self.object.get_absolute_url())
In my View
I am checking if price
field was updated and if yes update the price_date
field as well:
class PartView(ObjectView):
model = Part
form_class = PartForm
def form_valid(self, form):
if self.object:
old = Part.objects.get(id=self.object.id)
self.object = form.save(commit=False)
if self.object.price != old.price:
self.object.price_date = date.today()
self.object.save()
else:
self.object = form.save()
return super().form_valid(form)
I make an htmx
call to it from my template:
<div hx-target="this">
<form method="post"
hx-post="{{ hx_url }}"
hx-on:htmx:validation:failed="this.reportValidity()"
hx-trigger="click from:#btn-save">
{% csrf_token %}
{{ form.price }}
{{ form.price_date }}
</form>
{% include "btn_save.html" %}
</div>
The problem is even though it successfully updates the price_date
in the DB it still returns the form with the old value, and now if I press "Save" again, it will overwrite the previous change. Why does it happen?
That's because you're using the old form instance for re-rendering, which does not have the price date value changed.
To fix it, you should instantiate the form again, before passing it to the template context, eg
form = PartForm(instance=self.object)
return self.render_to_response(self.get_context_data(form=form))