mirror of
				https://github.com/django/django.git
				synced 2025-10-31 09:41:08 +00:00 
			
		
		
		
	[3.2.x] Fixed #32271 -- Improved consistency of docs CBV examples.
Co-Authored-By: Carles Pina i Estany <carles@pina.cat>
Backport of 5fd4f22d19 from master
			
			
This commit is contained in:
		
				
					committed by
					
						 Mariusz Felisiak
						Mariusz Felisiak
					
				
			
			
				
	
			
			
			
						parent
						
							7e6e822162
						
					
				
				
					commit
					9f277c3a7c
				
			| @@ -110,17 +110,17 @@ Now we need to define a view:: | ||||
|     from django.views.generic import ListView | ||||
|     from books.models import Publisher | ||||
|  | ||||
|     class PublisherList(ListView): | ||||
|     class PublisherListView(ListView): | ||||
|         model = Publisher | ||||
|  | ||||
| Finally hook that view into your urls:: | ||||
|  | ||||
|     # urls.py | ||||
|     from django.urls import path | ||||
|     from books.views import PublisherList | ||||
|     from books.views import PublisherListView | ||||
|  | ||||
|     urlpatterns = [ | ||||
|         path('publishers/', PublisherList.as_view()), | ||||
|         path('publishers/', PublisherListView.as_view()), | ||||
|     ] | ||||
|  | ||||
| That's all the Python code we need to write. We still need to write a template, | ||||
| @@ -183,7 +183,7 @@ specifies the context variable to use:: | ||||
|     from django.views.generic import ListView | ||||
|     from books.models import Publisher | ||||
|  | ||||
|     class PublisherList(ListView): | ||||
|     class PublisherListView(ListView): | ||||
|         model = Publisher | ||||
|         context_object_name = 'my_favorite_publishers' | ||||
|  | ||||
| @@ -210,7 +210,7 @@ you can override it to send more:: | ||||
|     from django.views.generic import DetailView | ||||
|     from books.models import Book, Publisher | ||||
|  | ||||
|     class PublisherDetail(DetailView): | ||||
|     class PublisherDetailView(DetailView): | ||||
|  | ||||
|         model = Publisher | ||||
|  | ||||
| @@ -254,7 +254,7 @@ specify the list of objects using the ``queryset`` argument:: | ||||
|     from django.views.generic import DetailView | ||||
|     from books.models import Publisher | ||||
|  | ||||
|     class PublisherDetail(DetailView): | ||||
|     class PublisherDetailView(DetailView): | ||||
|  | ||||
|         context_object_name = 'publisher' | ||||
|         queryset = Publisher.objects.all() | ||||
| @@ -273,7 +273,7 @@ with the most recent first:: | ||||
|     from django.views.generic import ListView | ||||
|     from books.models import Book | ||||
|  | ||||
|     class BookList(ListView): | ||||
|     class BookListView(ListView): | ||||
|         queryset = Book.objects.order_by('-publication_date') | ||||
|         context_object_name = 'book_list' | ||||
|  | ||||
| @@ -284,7 +284,7 @@ list of books by a particular publisher, you can use the same technique:: | ||||
|     from django.views.generic import ListView | ||||
|     from books.models import Book | ||||
|  | ||||
|     class AcmeBookList(ListView): | ||||
|     class AcmeBookListView(ListView): | ||||
|  | ||||
|         context_object_name = 'book_list' | ||||
|         queryset = Book.objects.filter(publisher__name='ACME Publishing') | ||||
| @@ -330,20 +330,20 @@ Here, we have a URLconf with a single captured group:: | ||||
|  | ||||
|     # urls.py | ||||
|     from django.urls import path | ||||
|     from books.views import PublisherBookList | ||||
|     from books.views import PublisherBookListView | ||||
|  | ||||
|     urlpatterns = [ | ||||
|         path('books/<publisher>/', PublisherBookList.as_view()), | ||||
|         path('books/<publisher>/', PublisherBookListView.as_view()), | ||||
|     ] | ||||
|  | ||||
| Next, we'll write the ``PublisherBookList`` view itself:: | ||||
| Next, we'll write the ``PublisherBookListView`` view itself:: | ||||
|  | ||||
|     # views.py | ||||
|     from django.shortcuts import get_object_or_404 | ||||
|     from django.views.generic import ListView | ||||
|     from books.models import Book, Publisher | ||||
|  | ||||
|     class PublisherBookList(ListView): | ||||
|     class PublisherBookListView(ListView): | ||||
|  | ||||
|         template_name = 'books/books_by_publisher.html' | ||||
|  | ||||
|   | ||||
| @@ -39,7 +39,7 @@ The view can be constructed using a ``FormView``: | ||||
|     from myapp.forms import ContactForm | ||||
|     from django.views.generic.edit import FormView | ||||
|  | ||||
|     class ContactView(FormView): | ||||
|     class ContactFormView(FormView): | ||||
|         template_name = 'contact.html' | ||||
|         form_class = ContactForm | ||||
|         success_url = '/thanks/' | ||||
| @@ -119,15 +119,15 @@ here; we don't have to write any logic ourselves: | ||||
|     from django.views.generic.edit import CreateView, DeleteView, UpdateView | ||||
|     from myapp.models import Author | ||||
|  | ||||
|     class AuthorCreate(CreateView): | ||||
|     class AuthorCreateView(CreateView): | ||||
|         model = Author | ||||
|         fields = ['name'] | ||||
|  | ||||
|     class AuthorUpdate(UpdateView): | ||||
|     class AuthorUpdateView(UpdateView): | ||||
|         model = Author | ||||
|         fields = ['name'] | ||||
|  | ||||
|     class AuthorDelete(DeleteView): | ||||
|     class AuthorDeleteView(DeleteView): | ||||
|         model = Author | ||||
|         success_url = reverse_lazy('author-list') | ||||
|  | ||||
| @@ -150,13 +150,13 @@ Finally, we hook these new views into the URLconf: | ||||
|     :caption: urls.py | ||||
|  | ||||
|     from django.urls import path | ||||
|     from myapp.views import AuthorCreate, AuthorDelete, AuthorUpdate | ||||
|     from myapp.views import AuthorCreateView, AuthorDeleteView, AuthorUpdateView | ||||
|  | ||||
|     urlpatterns = [ | ||||
|         # ... | ||||
|         path('author/add/', AuthorCreate.as_view(), name='author-add'), | ||||
|         path('author/<int:pk>/', AuthorUpdate.as_view(), name='author-update'), | ||||
|         path('author/<int:pk>/delete/', AuthorDelete.as_view(), name='author-delete'), | ||||
|         path('author/add/', AuthorCreateView.as_view(), name='author-add'), | ||||
|         path('author/<int:pk>/', AuthorUpdateView.as_view(), name='author-update'), | ||||
|         path('author/<int:pk>/delete/', AuthorDeleteView.as_view(), name='author-delete'), | ||||
|     ] | ||||
|  | ||||
| .. note:: | ||||
| @@ -210,7 +210,7 @@ to edit, and override | ||||
|     from django.views.generic.edit import CreateView | ||||
|     from myapp.models import Author | ||||
|  | ||||
|     class AuthorCreate(LoginRequiredMixin, CreateView): | ||||
|     class AuthorCreateView(LoginRequiredMixin, CreateView): | ||||
|         model = Author | ||||
|         fields = ['name'] | ||||
|  | ||||
| @@ -259,6 +259,6 @@ works with an API-based workflow as well as 'normal' form POSTs:: | ||||
|                 } | ||||
|                 return JsonResponse(data) | ||||
|  | ||||
|     class AuthorCreate(JsonableResponseMixin, CreateView): | ||||
|     class AuthorCreateView(JsonableResponseMixin, CreateView): | ||||
|         model = Author | ||||
|         fields = ['name'] | ||||
|   | ||||
| @@ -229,7 +229,7 @@ We'll demonstrate this with the ``Author`` model we used in the | ||||
|     from django.views.generic.detail import SingleObjectMixin | ||||
|     from books.models import Author | ||||
|  | ||||
|     class RecordInterest(SingleObjectMixin, View): | ||||
|     class RecordInterestView(SingleObjectMixin, View): | ||||
|         """Records the current user's interest in an author.""" | ||||
|         model = Author | ||||
|  | ||||
| @@ -256,11 +256,11 @@ We can hook this into our URLs easily enough: | ||||
|     :caption: urls.py | ||||
|  | ||||
|     from django.urls import path | ||||
|     from books.views import RecordInterest | ||||
|     from books.views import RecordInterestView | ||||
|  | ||||
|     urlpatterns = [ | ||||
|         #... | ||||
|         path('author/<int:pk>/interest/', RecordInterest.as_view(), name='author-interest'), | ||||
|         path('author/<int:pk>/interest/', RecordInterestView.as_view(), name='author-interest'), | ||||
|     ] | ||||
|  | ||||
| Note the ``pk`` named group, which | ||||
| @@ -307,13 +307,13 @@ object. In order to do this, we need to have two different querysets: | ||||
|     will add in the suitable ``page_obj`` and ``paginator`` for us | ||||
|     providing we remember to call ``super()``. | ||||
|  | ||||
| Now we can write a new ``PublisherDetail``:: | ||||
| Now we can write a new ``PublisherDetailView``:: | ||||
|  | ||||
|     from django.views.generic import ListView | ||||
|     from django.views.generic.detail import SingleObjectMixin | ||||
|     from books.models import Publisher | ||||
|  | ||||
|     class PublisherDetail(SingleObjectMixin, ListView): | ||||
|     class PublisherDetailView(SingleObjectMixin, ListView): | ||||
|         paginate_by = 2 | ||||
|         template_name = "books/publisher_detail.html" | ||||
|  | ||||
| @@ -434,7 +434,7 @@ code so that on ``POST`` the form gets called appropriately. | ||||
|     both of the views implement ``get()``, and things would get much more | ||||
|     confusing. | ||||
|  | ||||
| Our new ``AuthorDetail`` looks like this:: | ||||
| Our new ``AuthorDetailView`` looks like this:: | ||||
|  | ||||
|     # CAUTION: you almost certainly do not want to do this. | ||||
|     # It is provided as part of a discussion of problems you can | ||||
| @@ -451,7 +451,7 @@ Our new ``AuthorDetail`` looks like this:: | ||||
|     class AuthorInterestForm(forms.Form): | ||||
|         message = forms.CharField() | ||||
|  | ||||
|     class AuthorDetail(FormMixin, DetailView): | ||||
|     class AuthorDetailView(FormMixin, DetailView): | ||||
|         model = Author | ||||
|         form_class = AuthorInterestForm | ||||
|  | ||||
| @@ -504,8 +504,8 @@ clear division here: ``GET`` requests should get the | ||||
| data), and ``POST`` requests should get the :class:`FormView`. Let's | ||||
| set up those views first. | ||||
|  | ||||
| The ``AuthorDisplay`` view is almost the same as :ref:`when we | ||||
| first introduced AuthorDetail<generic-views-extra-work>`; we have to | ||||
| The ``AuthorDetailView`` view is almost the same as :ref:`when we | ||||
| first introduced AuthorDetailView<generic-views-extra-work>`; we have to | ||||
| write our own ``get_context_data()`` to make the | ||||
| ``AuthorInterestForm`` available to the template. We'll skip the | ||||
| ``get_object()`` override from before for clarity:: | ||||
| @@ -517,7 +517,7 @@ write our own ``get_context_data()`` to make the | ||||
|     class AuthorInterestForm(forms.Form): | ||||
|         message = forms.CharField() | ||||
|  | ||||
|     class AuthorDisplay(DetailView): | ||||
|     class AuthorDetailView(DetailView): | ||||
|         model = Author | ||||
|  | ||||
|         def get_context_data(self, **kwargs): | ||||
| @@ -525,18 +525,18 @@ write our own ``get_context_data()`` to make the | ||||
|             context['form'] = AuthorInterestForm() | ||||
|             return context | ||||
|  | ||||
| Then the ``AuthorInterest`` is a :class:`FormView`, but we have to bring in | ||||
| Then the ``AuthorInterestForm`` is a :class:`FormView`, but we have to bring in | ||||
| :class:`~django.views.generic.detail.SingleObjectMixin` so we can find the | ||||
| author we're talking about, and we have to remember to set ``template_name`` to | ||||
| ensure that form errors will render the same template as ``AuthorDisplay`` is | ||||
| using on ``GET``:: | ||||
| ensure that form errors will render the same template as ``AuthorDetailView`` | ||||
| is using on ``GET``:: | ||||
|  | ||||
|     from django.http import HttpResponseForbidden | ||||
|     from django.urls import reverse | ||||
|     from django.views.generic import FormView | ||||
|     from django.views.generic.detail import SingleObjectMixin | ||||
|  | ||||
|     class AuthorInterest(SingleObjectMixin, FormView): | ||||
|     class AuthorInterestFormView(SingleObjectMixin, FormView): | ||||
|         template_name = 'books/author_detail.html' | ||||
|         form_class = AuthorInterestForm | ||||
|         model = Author | ||||
| @@ -550,26 +550,26 @@ using on ``GET``:: | ||||
|         def get_success_url(self): | ||||
|             return reverse('author-detail', kwargs={'pk': self.object.pk}) | ||||
|  | ||||
| Finally we bring this together in a new ``AuthorDetail`` view. We | ||||
| Finally we bring this together in a new ``AuthorView`` view. We | ||||
| already know that calling :meth:`~django.views.generic.base.View.as_view()` on | ||||
| a class-based view gives us something that behaves exactly like a function | ||||
| based view, so we can do that at the point we choose between the two subviews. | ||||
|  | ||||
| You can pass through keyword arguments to | ||||
| :meth:`~django.views.generic.base.View.as_view()` in the same way you | ||||
| would in your URLconf, such as if you wanted the ``AuthorInterest`` behavior | ||||
| to also appear at another URL but using a different template:: | ||||
| would in your URLconf, such as if you wanted the ``AuthorInterestFormView`` | ||||
| behavior to also appear at another URL but using a different template:: | ||||
|  | ||||
|     from django.views import View | ||||
|  | ||||
|     class AuthorDetail(View): | ||||
|     class AuthorView(View): | ||||
|  | ||||
|         def get(self, request, *args, **kwargs): | ||||
|             view = AuthorDisplay.as_view() | ||||
|             view = AuthorDetailView.as_view() | ||||
|             return view(request, *args, **kwargs) | ||||
|  | ||||
|         def post(self, request, *args, **kwargs): | ||||
|             view = AuthorInterest.as_view() | ||||
|             view = AuthorInterestFormView.as_view() | ||||
|             return view(request, *args, **kwargs) | ||||
|  | ||||
| This approach can also be used with any other generic class-based | ||||
|   | ||||
		Reference in New Issue
	
	Block a user