request
). This means that the minimum representation will be very simple:
from django.http import HttpResponse def hello_world(request): return HttpResponse("Hello, World")
View
doc class and implements the supported HTTP methods. Below is a very small representation of “Hello, World” written by us earlier, but executed as a class-representation:
from django.http import HttpResponse from django.views.generic import View class MyView(View): def get(self, request, *args, **kwargs): return HttpResponse("Hello, World")
get
class method. In the same way as when implemented by a function, this method takes the request object as the first parameter and returns an HTTP response.
Note: Valid Signatures
You may notice several additional arguments in the function signature compared to the representation we wrote earlier, in particular*args
and**kwargs
. CBVs were first created to make Django’s “generic” representations more flexible. The implication was that they would be used in a variety of different contexts, with potentially different arguments extracted from the URL. Being engaged in the last year of writing class representations, I continue to write them using valid signatures, and each time this turns out to be useful in unexpected situations.
views.py
file of our contacts
application, type the following code:
from django.views.generic import ListView from contacts.models import Contact class ListContactView(ListView): model = Contact
ListView
doc class, from which we inherited the view, is itself composed of several impurities that implement some behavior. This gives us great power with a small amount of code. In our case, we specified a model ( model = Contact
), which will force this view to list all contacts of the Contact
model from our database.
urlpatterns
variable of the urlpatterns
file.
addressbook/urls.py
URL template for our view that displays a list of contacts:
from django.conf.urls import patterns, include, url import contacts.views urlpatterns = patterns('', url(r'^$', contacts.views.ListContactView.as_view(), name='contacts-list',), )
url()
function is not strictly required, but I prefer to use it: when you start adding more information to URL patterns, it will allow you to use named parameters, making the code more clean;url()
is a regular expression. Notice the trailing character $
; Why do you think it is important?as_view()
. This method returns a wrapper over our class that the Django URL Manager can call;urlpatterns
variable must be defined, Django also allows you to define several other values ​​( variables ) for exceptions. These values ​​include handler403
, handler404
, and handler500
, which tell Django which view to use in case of an HTTP error. For more information, see the Django URL configuration documentation .
Note: Error importing URL configuration
Django loads the URL configuration very early during startup and tries to import modules found inside. If at least one of the import operations fails, the error message may be a little confusing. If your project has stopped working due to an import error, try importing the URL configuration in an interactive shell. This allows, in most cases, to determine where the problem occurred.
(venv:tutorial)$ python ./manage.py runserver 0.0.0.0:8080 Validating models... 0 errors found November 04, 2014 - 15:25:05 Django version 1.6.7, using settings 'addressbook.settings' Starting development server at http://0.0.0.0:8080/ Quit the server with CONTROL-C.
TemplateDoesNotExists
error
Translator's Note:
localhost
if you start the browser from the same host where the server is running. If your server is running on another host (like mine) - instead oflocalhost
specify the IP address of this host (in my case it is192.168.1.51
).
ListView
we used) have a predefined template name that they expect to find. We can see in this error message that the view expected to find a template file named contact_list.html
, which was derived from the model name. Let's create such a template.
settings.TEMPLATE_DIRS
. General views expect patterns to be found in the application directory (in this case, in the contacts
directory), and the file name will contain the model name (in this case, the expected file name: contact_list.html
). This comes in handy when you develop applications for reuse: the user of your application can create their own templates that will override the default templates and they will be stored in a directory directly associated with the application.
Translator's Note:
Django expects the template to be located at_/templates/_/_
template_name
property of our class view. Let's add one line to views.py
:
from django.views.generic import ListView from contacts.models import Contact class ListContactView(ListView): model = Contact template_name = 'contact_list.html'
templates
subdirectory in the contacts
directory (this is the directory with the application), and in it create the contact_list.html
template contact_list.html
:
<h1>Contacts</h1> <ul> {% for contact in object_list %} <li class="contact">{{ contact }}</li> {% endfor %} </ul>
views.py
file we will add a few lines:
from django.core.urlresolvers import reverse from django.views.generic import ListView from django.views.generic import CreateView from contacts.models import Contact class ListContactView(ListView): model = Contact template_name = 'contact_list.html' class CreateContactView(CreateView): model = Contact template_name = 'edit_contact.html' def get_success_url(self): return reverse('contacts-list')
Translator's Note:
If you are using Django version> = 1.7, then you can add an additional field to theCreateContactView
class:
fields = ['first_name', 'last_name', 'email']
This is not necessary, but since Django 1.7, the disuse of this field in classes with automatic generation of forms has been declared obsolete (they will tell you about this when running the tests). If you do not specify it, then all fields will be used in the edit form, but from Django 1.8 version this behavior will be removed.
get_success_url()
method, as we did. In our case, we use the reverse
function to calculate the URL of the contact list.
Note: Context variables in class views
The set of variables available in a template when it is displayed is called a context . Context is a combination of data from the view and information from the context processors .
When you use built-in generic views, it’s not at all obvious what variables are available in context. Over time, you will discover that their names (provided by common concepts into the context of the template) are fairly consistent —form
,object
andobject_list
are often used — although this will not help you at the beginning of the path. Fortunately, the documentation on this issue has become prettier since Django 1.5.
In classget_context_data()
method is used to add information to the context. If you overload this method, you will need to enable**kwargs
and call the superclass.
contacts/templates/edit_contact.html
will look something like this:
<h1>Add Contact</h1> <form action="{% url "contacts-new" %}" 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>
form
from context is the Django Form for our model. Since we didn’t specify one of our own, Django created one for us. How thoughtful;{{ form }}
we would get table rows; but we add .as_ul
, which forces output fields to be displayed as elements of an unordered list. Try using .as_p
and see what happens;/>
, ;
{% csrf_token %}
inserts a hidden field by which Django determines that the request came from your project and that it is not a cross-site request forgery ( CSRF ). Try not to include it in the template: you will still have access to the page, but as soon as you try to submit the form, you will get an error;
url
template tag to generate a link back to the contact list. Notice that contacts-list
is the name of our view, which we specified in the URL settings. Using url
instead of full path, we don’t have to worry about broken links. url
in the template is equivalent to reverse
in Python code.
Source: https://habr.com/ru/post/242261/