Reputation: 189
I'm following a tutorial on effectivedjango.com, and this is the code they have:
views.py:
class CreateContactView(CreateView):
model = Contact
template_name = 'edit_contact.html'
fields = '__all__' #this is needed for error msg Using ModelFormMixin (base class of CreateContactView) without the 'fields' attribute is prohibited.
def get_success_url(self):
return reverse('contacts-list')
def get_context_data(self, **kwargs):
context = super(CreateContactView, self).get_context_data(**kwargs)
context['action'] = reverse('contacts-new')
return context
class UpdateContactView(UpdateView):
model = Contact
template_name = 'edit_contact.html'
fields = '__all__'
def get_success_url(self):
return reverse('contacts-list')
def get_context_data(self, **kwargs):
context = super(UpdateContactView, self).get_context_data(**kwargs)
context['action'] = reverse('contacts-edit', kwargs={'pk' : self.get_object().id})
return context
urls.py:
url(r'^$', contacts.views.ListContactView.as_view(),
name='contacts-list',),
url(r'^new$', contacts.views.CreateContactView.as_view(),
name='contacts-new',),
url(r'^edit/(?P<pk>\d+)/$', contacts.views.UpdateContactView.as_view(),
name='contacts-edit',),
contact_list.html:
{% block content %}
<h1>Contacts</h1>
<ul>
{% for contact in object_list %}
<li class="contact">
<a href="{{ contact.get_absolute_url }}">{{ contact }}</a>
(<a href="{% url "contacts-edit" pk=contact.id %}">edit</a>)
</li>
{% endfor %}
</ul>
<a href="{% url "contacts-new" %}">Add contact</a>
{% endblock %}
edit_contact.html:
{% block content %}
{% if contact.id %}
<h1>Edit Contact</h1>
{% else %}
<h1>Add Contact</h1>
{% endif %}
<form action="{{ action }}" method="POST">
{% csrf_token %}
<ul>
{{ form.as_ul }}
</ul>
<input id="save_contact" type="submit" value="Save" />
</form>
<a href="{% url "contacts-list" %}">Back to list</a>
{% if contact.id %}
<a href="{% url "contacts-delete" pk=contact.id %}">Delete</a>
{% endif %}
{% endblock %}
Why does the line context['action'] = reverse('contacts-edit', kwargs={'pk' : self.get_object().id})
in views.py
look like its calling itself?
What I mean is, this action is called when the submit button is pressed in the contact-edit
template, correct? So it starts there, and it is reverse-calling contact-edit
which is itself, right?
What am I not seeing here?
Thank you for all your help.
Upvotes: 2
Views: 1165
Reputation: 47886
Yes, the line context['action'] = reverse('contacts-edit', kwargs={'pk' : self.get_object().id})
in views.py
is calling itself. This line generates the proper url for contacts-edit
view.
This is done so that POST
requests come to the same view i.e. UpdateContactView
which is an UpdateView
. There, proper handling will be done i.e. form validation will occur with the sent data. If the form is valid, object will be updated. Otherwise, the form will be displayed again with errors.
Django docs on UpdateView
:
A view that displays a form for editing an existing object, redisplaying the form with validation errors (if there are any) and saving changes to the object.
Upvotes: 2