I have two UpdateViews, one works and the other doesn't... Please see Update IV
The working model is:
views.py
class JuryUpdate(UpdateView):
model = Jury
fields = [
'jury_name',
]
template_name_suffix = '_update_form'
def get_object(self, *args, **kwargs):
return get_object_or_404(Jury, jury_id=self.kwargs['jr'])
def form_valid(self, form):
form.instance.customer_id = self.kwargs['pk']
form.instance.court_year = self.kwargs['yr']
form.instance.jury_id = self.kwargs['jr']
return super(JuryUpdate, self).form_valid(form)
templates/jury_update_form.html (in relevant part)
<div class="container">
<h5>Update {{for.instance.jury_name}}</h5>
<form method="post">{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Save" />
</form>
</div>
This setup will render an updateview with the object labels and existing field data from the object. This next setup doesn't work...
views.py
class CustomerUpdate(UpdateView):
model = Customer
fields = [
'customer',
]
template_name_suffix = '_update_form'
def get_object(self, *args, **kwargs):
return get_object_or_404(Customer, customer_id=self.kwargs['pk'])
def form_valid(self, form):
form.instance.customer_id = self.kwargs['pk']
return super(CustomerUpdate, self).form_valid(form)
templates/customer_update_form.html (in relevant part)
<div class="container">
<h5>Update {{form.instance.customer}}</h5>
<form method="post">{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Save" />
</form>
</div>
The second updateview does provide an update form but it doesn't populate with the calling object's data. It would seem that the object is there since the {{form.instance.customer}}
contains the correct customer
data for the call (no different than the JuryUpdate view).
I've tried to explicitly call get_initial
(as described here) and print, but the result is {}
. I've also tried variation of the form_valid
call but as presented above, I believe I'm getting the correct object. There are several examples (such as here) that use get_initial
to pre-populate with existing information - but that doesn't work in this instance and it isn't needed in my JuryUpdate
view.
Any help is appreciated.
UPDATE I
models.py
class Customer(models.Model):
class Meta:
verbose_name = "Customer"
verbose_name_plural = "Customers"
customer_id = models.AutoField(
primary_key=True)
customer = models.CharField(
max_length=40)
# table fields
def get_absolute_url(self):
return reverse(
'customer-detail-view',
kwargs={'pk':self.pk})
def __str__(self):
return self.customer
class Jury(models.Model):
class Meta:
verbose_name = "Jury"
verbose_name_plural = "Juries"
customer = models.ForeignKey(
Customer,
on_delete=models.CASCADE)
court_year = models.ForeignKey(
CourtYear,
on_delete=models.CASCADE)
jury_id = models.AutoField(
primary_key=True)
jury_name = models.CharField(
max_length=20)
# other table fields
def get_absolute_url(self):
return reverse(
'jury-list-view',
kwargs={'pk':self.customer_id, 'yr':self.court_year_id})
def __str__(self):
return self.jury_name
urls.py
path('add_customer/', views.CustomerCreate.as_view(), name='customer-add'),
path('<int:pk>/', views.CustomerDetailView.as_view(), name='customer-detail-view'),
path('<int:pk>/delete/', views.CustomerDelete.as_view(), name='customer-delete'),
path('<int:pk>/update/', views.CustomerUpdate.as_view(), name='customer-update'),
path('<int:pk>/<int:yr>/', views.JuryListView.as_view(), name='jury-list-view'),
path('<int:pk>/<int:yr>/add_jury/', views.JuryCreate.as_view(), name='jury-add'),
path('<int:pk>/<int:yr>/<int:jr>/updatejury', views.JuryUpdate.as_view(), name='jury-update'),
path('<int:pk>/<int:yr>/<int:jr>/deletejury', views.JuryDelete.as_view(), name='jury-delete'),
UPDATE II
I've added a get_initial()
method to my CustomerUpdate(UpdateView)
as follows:
def get_initial(self):
initial = super(CustomerUpdate, self).get_initial()
print('initial data', initial)
customer_object = self.get_object()
initial['customer'] = customer_object.customer
# other fields omitted...
print('initial data updated', initial)
return initial
The initial data
print returns {}
. The initial data updated
print returns {'customer': 'John Doe'}
(plus the "other fields"). So it seems that the right information is getting pulled and delivered - It must be in the html
?
Update III
I've taken the CustomerUpdate(UpdateView)
down to the very basic class model:
class CustomerUpdate(UpdateView):
model = Customer
fields = [
'customer',
]
template_name_suffix = '_update_form'
The template is already the basic format (docs) - the rendered webpage still doesn't have object data for updating...
Update IV
I think I've figured out the problem - but don't know how to fix...
When I use the JuryUpdate
call the console shows:
[02/Jun/2018 16:19:19] "GET /myapp/1/3/9/updatejury/?csrfmiddlewaretoken=1kHK4xgqdbBfXsv6mtz0WKgKpewFwLVtpUX5Z51qnLsGaMDVmpdVHKslXAXPhvY8 HTTP/1.1" 200 3687
When I use the CustomerUpdate
call the console shows:
[02/Jun/2018 16:18:57] "POST /myapp/5/update/ HTTP/1.1" 200 3354
So my updateview on the Jury update is a GET
call while my udpateview on Customer is aPOST
call. In looking through the docs, I can see that the GET
call with show the data while the POST
call is (I think) assuming a black data set. I can't figure out why I'm getting a different result - where would this be set/changed?