diff options
| author | django-bot <ops@djangoproject.com> | 2023-02-28 20:53:28 +0100 |
|---|---|---|
| committer | Mariusz Felisiak <felisiak.mariusz@gmail.com> | 2023-03-01 13:03:56 +0100 |
| commit | 14459f80ee3a9e005989db37c26fd13bb6d2fab2 (patch) | |
| tree | eb62429ed696ed3a5389f3a676aecfc6d15a99cc /docs/intro | |
| parent | 6015bab80e28aef2669f6fac53423aa65f70cb08 (diff) | |
Fixed #34140 -- Reformatted code blocks in docs with blacken-docs.
Diffstat (limited to 'docs/intro')
| -rw-r--r-- | docs/intro/contributing.txt | 4 | ||||
| -rw-r--r-- | docs/intro/overview.txt | 29 | ||||
| -rw-r--r-- | docs/intro/reusable-apps.txt | 4 | ||||
| -rw-r--r-- | docs/intro/tutorial01.txt | 6 | ||||
| -rw-r--r-- | docs/intro/tutorial02.txt | 28 | ||||
| -rw-r--r-- | docs/intro/tutorial03.txt | 49 | ||||
| -rw-r--r-- | docs/intro/tutorial04.txt | 46 | ||||
| -rw-r--r-- | docs/intro/tutorial05.txt | 49 | ||||
| -rw-r--r-- | docs/intro/tutorial07.txt | 45 |
9 files changed, 143 insertions, 117 deletions
diff --git a/docs/intro/contributing.txt b/docs/intro/contributing.txt index 0a9189e907..c8601cb14d 100644 --- a/docs/intro/contributing.txt +++ b/docs/intro/contributing.txt @@ -326,7 +326,7 @@ Navigate to Django's ``tests/shortcuts/`` folder and create a new file class MakeToastTests(SimpleTestCase): def test_make_toast(self): - self.assertEqual(make_toast(), 'toast') + self.assertEqual(make_toast(), "toast") This test checks that the ``make_toast()`` returns ``'toast'``. @@ -375,7 +375,7 @@ Navigate to the ``django/`` folder and open the ``shortcuts.py`` file. At the bottom, add:: def make_toast(): - return 'toast' + return "toast" Now we need to make sure that the test we wrote earlier passes, so we can see whether the code we added is working correctly. Again, navigate to the Django diff --git a/docs/intro/overview.txt b/docs/intro/overview.txt index efdf77b1d9..8314b3d351 100644 --- a/docs/intro/overview.txt +++ b/docs/intro/overview.txt @@ -30,12 +30,14 @@ database-schema problems. Here's a quick example: from django.db import models + class Reporter(models.Model): full_name = models.CharField(max_length=70) def __str__(self): return self.full_name + class Article(models.Model): pub_date = models.DateField() headline = models.CharField(max_length=200) @@ -78,7 +80,7 @@ necessary: <QuerySet []> # Create a new Reporter. - >>> r = Reporter(full_name='John Smith') + >>> r = Reporter(full_name="John Smith") # Save the object into the database. You have to call save() explicitly. >>> r.save() @@ -98,9 +100,9 @@ necessary: # Django provides a rich database lookup API. >>> Reporter.objects.get(id=1) <Reporter: John Smith> - >>> Reporter.objects.get(full_name__startswith='John') + >>> Reporter.objects.get(full_name__startswith="John") <Reporter: John Smith> - >>> Reporter.objects.get(full_name__contains='mith') + >>> Reporter.objects.get(full_name__contains="mith") <Reporter: John Smith> >>> Reporter.objects.get(id=2) Traceback (most recent call last): @@ -109,8 +111,9 @@ necessary: # Create an article. >>> from datetime import date - >>> a = Article(pub_date=date.today(), headline='Django is cool', - ... content='Yeah.', reporter=r) + >>> a = Article( + ... pub_date=date.today(), headline="Django is cool", content="Yeah.", reporter=r + ... ) >>> a.save() # Now the article is in the database. @@ -129,11 +132,11 @@ necessary: # The API follows relationships as far as you need, performing efficient # JOINs for you behind the scenes. # This finds all articles by a reporter whose name starts with "John". - >>> Article.objects.filter(reporter__full_name__startswith='John') + >>> Article.objects.filter(reporter__full_name__startswith="John") <QuerySet [<Article: Django is cool>]> # Change an object by altering its attributes and calling save(). - >>> r.full_name = 'Billy Goat' + >>> r.full_name = "Billy Goat" >>> r.save() # Delete an object with delete(). @@ -152,6 +155,7 @@ only step required is to register your model in the admin site: from django.db import models + class Article(models.Model): pub_date = models.DateField() headline = models.CharField(max_length=200) @@ -198,9 +202,9 @@ example above: from . import views urlpatterns = [ - path('articles/<int:year>/', views.year_archive), - path('articles/<int:year>/<int:month>/', views.month_archive), - path('articles/<int:year>/<int:month>/<int:pk>/', views.article_detail), + path("articles/<int:year>/", views.year_archive), + path("articles/<int:year>/<int:month>/", views.month_archive), + path("articles/<int:year>/<int:month>/<int:pk>/", views.article_detail), ] The code above maps URL paths to Python callback functions ("views"). The path @@ -237,10 +241,11 @@ and renders the template with the retrieved data. Here's an example view for from .models import Article + def year_archive(request, year): a_list = Article.objects.filter(pub_date__year=year) - context = {'year': year, 'article_list': a_list} - return render(request, 'news/year_archive.html', context) + context = {"year": year, "article_list": a_list} + return render(request, "news/year_archive.html", context) This example uses Django's :doc:`template system </topics/templates>`, which has several powerful features but strives to stay simple enough for non-programmers diff --git a/docs/intro/reusable-apps.txt b/docs/intro/reusable-apps.txt index 5fc72ab6d7..f402b6081e 100644 --- a/docs/intro/reusable-apps.txt +++ b/docs/intro/reusable-apps.txt @@ -164,12 +164,12 @@ this. For a small app like polls, this process isn't too difficult. INSTALLED_APPS = [ ..., - 'polls', + "polls", ] 2. Include the polls URLconf in your project urls.py like this:: - path('polls/', include('polls.urls')), + path("polls/", include("polls.urls")), 3. Run ``python manage.py migrate`` to create the polls models. diff --git a/docs/intro/tutorial01.txt b/docs/intro/tutorial01.txt index d9142e7a03..cb296129c0 100644 --- a/docs/intro/tutorial01.txt +++ b/docs/intro/tutorial01.txt @@ -286,7 +286,7 @@ In the ``polls/urls.py`` file include the following code: from . import views urlpatterns = [ - path('', views.index, name='index'), + path("", views.index, name="index"), ] The next step is to point the root URLconf at the ``polls.urls`` module. In @@ -300,8 +300,8 @@ The next step is to point the root URLconf at the ``polls.urls`` module. In from django.urls import include, path urlpatterns = [ - path('polls/', include('polls.urls')), - path('admin/', admin.site.urls), + path("polls/", include("polls.urls")), + path("admin/", admin.site.urls), ] The :func:`~django.urls.include` function allows referencing other URLconfs. diff --git a/docs/intro/tutorial02.txt b/docs/intro/tutorial02.txt index e01975aeed..6ba70ddc1c 100644 --- a/docs/intro/tutorial02.txt +++ b/docs/intro/tutorial02.txt @@ -148,7 +148,7 @@ These concepts are represented by Python classes. Edit the class Question(models.Model): question_text = models.CharField(max_length=200) - pub_date = models.DateTimeField('date published') + pub_date = models.DateTimeField("date published") class Choice(models.Model): @@ -220,13 +220,13 @@ this: :caption: ``mysite/settings.py`` INSTALLED_APPS = [ - 'polls.apps.PollsConfig', - 'django.contrib.admin', - 'django.contrib.auth', - 'django.contrib.contenttypes', - 'django.contrib.sessions', - 'django.contrib.messages', - 'django.contrib.staticfiles', + "polls.apps.PollsConfig", + "django.contrib.admin", + "django.contrib.auth", + "django.contrib.contenttypes", + "django.contrib.sessions", + "django.contrib.messages", + "django.contrib.staticfiles", ] Now Django knows to include the ``polls`` app. Let's run another command: @@ -430,11 +430,13 @@ representation of this object. Let's fix that by editing the ``Question`` model from django.db import models + class Question(models.Model): # ... def __str__(self): return self.question_text + class Choice(models.Model): # ... def __str__(self): @@ -484,7 +486,7 @@ Save these changes and start a new Python interactive shell by running # keyword arguments. >>> Question.objects.filter(id=1) <QuerySet [<Question: What's up?>]> - >>> Question.objects.filter(question_text__startswith='What') + >>> Question.objects.filter(question_text__startswith="What") <QuerySet [<Question: What's up?>]> # Get the question that was published this year. @@ -522,11 +524,11 @@ Save these changes and start a new Python interactive shell by running <QuerySet []> # Create three choices. - >>> q.choice_set.create(choice_text='Not much', votes=0) + >>> q.choice_set.create(choice_text="Not much", votes=0) <Choice: Not much> - >>> q.choice_set.create(choice_text='The sky', votes=0) + >>> q.choice_set.create(choice_text="The sky", votes=0) <Choice: The sky> - >>> c = q.choice_set.create(choice_text='Just hacking again', votes=0) + >>> c = q.choice_set.create(choice_text="Just hacking again", votes=0) # Choice objects have API access to their related Question objects. >>> c.question @@ -547,7 +549,7 @@ Save these changes and start a new Python interactive shell by running <QuerySet [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]> # Let's delete one of the choices. Use delete() for that. - >>> c = q.choice_set.filter(choice_text__startswith='Just hacking') + >>> c = q.choice_set.filter(choice_text__startswith="Just hacking") >>> c.delete() For more information on model relations, see :doc:`Accessing related objects diff --git a/docs/intro/tutorial03.txt b/docs/intro/tutorial03.txt index c0b3b00a51..04bd83ae52 100644 --- a/docs/intro/tutorial03.txt +++ b/docs/intro/tutorial03.txt @@ -75,10 +75,12 @@ slightly different, because they take an argument: def detail(request, question_id): return HttpResponse("You're looking at question %s." % question_id) + def results(request, question_id): response = "You're looking at the results of question %s." return HttpResponse(response % question_id) + def vote(request, question_id): return HttpResponse("You're voting on question %s." % question_id) @@ -94,13 +96,13 @@ Wire these new views into the ``polls.urls`` module by adding the following urlpatterns = [ # ex: /polls/ - path('', views.index, name='index'), + path("", views.index, name="index"), # ex: /polls/5/ - path('<int:question_id>/', views.detail, name='detail'), + path("<int:question_id>/", views.detail, name="detail"), # ex: /polls/5/results/ - path('<int:question_id>/results/', views.results, name='results'), + path("<int:question_id>/results/", views.results, name="results"), # ex: /polls/5/vote/ - path('<int:question_id>/vote/', views.vote, name='vote'), + path("<int:question_id>/vote/", views.vote, name="vote"), ] Take a look in your browser, at "/polls/34/". It'll run the ``detail()`` @@ -157,10 +159,11 @@ commas, according to publication date: def index(request): - latest_question_list = Question.objects.order_by('-pub_date')[:5] - output = ', '.join([q.question_text for q in latest_question_list]) + latest_question_list = Question.objects.order_by("-pub_date")[:5] + output = ", ".join([q.question_text for q in latest_question_list]) return HttpResponse(output) + # Leave the rest of the views (detail, results, vote) unchanged There's a problem here, though: the page's design is hard-coded in the view. If @@ -229,10 +232,10 @@ Now let's update our ``index`` view in ``polls/views.py`` to use the template: def index(request): - latest_question_list = Question.objects.order_by('-pub_date')[:5] - template = loader.get_template('polls/index.html') + latest_question_list = Question.objects.order_by("-pub_date")[:5] + template = loader.get_template("polls/index.html") context = { - 'latest_question_list': latest_question_list, + "latest_question_list": latest_question_list, } return HttpResponse(template.render(context, request)) @@ -261,9 +264,9 @@ rewritten: def index(request): - latest_question_list = Question.objects.order_by('-pub_date')[:5] - context = {'latest_question_list': latest_question_list} - return render(request, 'polls/index.html', context) + latest_question_list = Question.objects.order_by("-pub_date")[:5] + context = {"latest_question_list": latest_question_list} + return render(request, "polls/index.html", context) Note that once we've done this in all these views, we no longer need to import :mod:`~django.template.loader` and :class:`~django.http.HttpResponse` (you'll @@ -288,13 +291,15 @@ for a given poll. Here's the view: from django.shortcuts import render from .models import Question + + # ... def detail(request, question_id): try: question = Question.objects.get(pk=question_id) except Question.DoesNotExist: raise Http404("Question does not exist") - return render(request, 'polls/detail.html', {'question': question}) + return render(request, "polls/detail.html", {"question": question}) The new concept here: The view raises the :exc:`~django.http.Http404` exception if a question with the requested ID doesn't exist. @@ -323,10 +328,12 @@ provides a shortcut. Here's the ``detail()`` view, rewritten: from django.shortcuts import get_object_or_404, render from .models import Question + + # ... def detail(request, question_id): question = get_object_or_404(Question, pk=question_id) - return render(request, 'polls/detail.html', {'question': question}) + return render(request, "polls/detail.html", {"question": question}) The :func:`~django.shortcuts.get_object_or_404` function takes a Django model as its first argument and an arbitrary number of keyword arguments, which it @@ -408,7 +415,7 @@ defined below:: ... # the 'name' value as called by the {% url %} template tag - path('<int:question_id>/', views.detail, name='detail'), + path("<int:question_id>/", views.detail, name="detail"), ... If you want to change the URL of the polls detail view to something else, @@ -417,7 +424,7 @@ template (or templates) you would change it in ``polls/urls.py``:: ... # added the word 'specifics' - path('specifics/<int:question_id>/', views.detail, name='detail'), + path("specifics/<int:question_id>/", views.detail, name="detail"), ... Namespacing URL names @@ -440,12 +447,12 @@ file, go ahead and add an ``app_name`` to set the application namespace: from . import views - app_name = 'polls' + app_name = "polls" urlpatterns = [ - path('', views.index, name='index'), - path('<int:question_id>/', views.detail, name='detail'), - path('<int:question_id>/results/', views.results, name='results'), - path('<int:question_id>/vote/', views.vote, name='vote'), + path("", views.index, name="index"), + path("<int:question_id>/", views.detail, name="detail"), + path("<int:question_id>/results/", views.results, name="results"), + path("<int:question_id>/vote/", views.vote, name="vote"), ] Now change your ``polls/index.html`` template from: diff --git a/docs/intro/tutorial04.txt b/docs/intro/tutorial04.txt index 5deb80047d..726808a93d 100644 --- a/docs/intro/tutorial04.txt +++ b/docs/intro/tutorial04.txt @@ -66,7 +66,7 @@ created a URLconf for the polls application that includes this line: .. code-block:: python :caption: ``polls/urls.py`` - path('<int:question_id>/vote/', views.vote, name='vote'), + path("<int:question_id>/vote/", views.vote, name="vote"), We also created a dummy implementation of the ``vote()`` function. Let's create a real version. Add the following to ``polls/views.py``: @@ -79,24 +79,30 @@ create a real version. Add the following to ``polls/views.py``: from django.urls import reverse from .models import Choice, Question + + # ... def vote(request, question_id): question = get_object_or_404(Question, pk=question_id) try: - selected_choice = question.choice_set.get(pk=request.POST['choice']) + selected_choice = question.choice_set.get(pk=request.POST["choice"]) except (KeyError, Choice.DoesNotExist): # Redisplay the question voting form. - return render(request, 'polls/detail.html', { - 'question': question, - 'error_message': "You didn't select a choice.", - }) + return render( + request, + "polls/detail.html", + { + "question": question, + "error_message": "You didn't select a choice.", + }, + ) else: selected_choice.votes += 1 selected_choice.save() # Always return an HttpResponseRedirect after successfully dealing # with POST data. This prevents data from being posted twice if a # user hits the Back button. - return HttpResponseRedirect(reverse('polls:results', args=(question.id,))) + return HttpResponseRedirect(reverse("polls:results", args=(question.id,))) This code includes a few things we haven't covered yet in this tutorial: @@ -138,7 +144,7 @@ This code includes a few things we haven't covered yet in this tutorial: this :func:`~django.urls.reverse` call will return a string like :: - '/polls/3/results/' + "/polls/3/results/" where the ``3`` is the value of ``question.id``. This redirected URL will then call the ``'results'`` view to display the final page. @@ -159,7 +165,7 @@ page for the question. Let's write that view: def results(request, question_id): question = get_object_or_404(Question, pk=question_id) - return render(request, 'polls/results.html', {'question': question}) + return render(request, "polls/results.html", {"question": question}) This is almost exactly the same as the ``detail()`` view from :doc:`Tutorial 3 </intro/tutorial03>`. The only difference is the template name. We'll fix this @@ -246,12 +252,12 @@ First, open the ``polls/urls.py`` URLconf and change it like so: from . import views - app_name = 'polls' + app_name = "polls" urlpatterns = [ - path('', views.IndexView.as_view(), name='index'), - path('<int:pk>/', views.DetailView.as_view(), name='detail'), - path('<int:pk>/results/', views.ResultsView.as_view(), name='results'), - path('<int:question_id>/vote/', views.vote, name='vote'), + path("", views.IndexView.as_view(), name="index"), + path("<int:pk>/", views.DetailView.as_view(), name="detail"), + path("<int:pk>/results/", views.ResultsView.as_view(), name="results"), + path("<int:question_id>/vote/", views.vote, name="vote"), ] Note that the name of the matched pattern in the path strings of the second and @@ -276,26 +282,26 @@ views and use Django's generic views instead. To do so, open the class IndexView(generic.ListView): - template_name = 'polls/index.html' - context_object_name = 'latest_question_list' + template_name = "polls/index.html" + context_object_name = "latest_question_list" def get_queryset(self): """Return the last five published questions.""" - return Question.objects.order_by('-pub_date')[:5] + return Question.objects.order_by("-pub_date")[:5] class DetailView(generic.DetailView): model = Question - template_name = 'polls/detail.html' + template_name = "polls/detail.html" class ResultsView(generic.DetailView): model = Question - template_name = 'polls/results.html' + template_name = "polls/results.html" def vote(request, question_id): - ... # same as above, no changes needed. + ... # same as above, no changes needed. We're using two generic views here: :class:`~django.views.generic.list.ListView` and diff --git a/docs/intro/tutorial05.txt b/docs/intro/tutorial05.txt index 8eff8bf9d4..2e218bd331 100644 --- a/docs/intro/tutorial05.txt +++ b/docs/intro/tutorial05.txt @@ -183,7 +183,6 @@ Put the following in the ``tests.py`` file in the ``polls`` application: class QuestionModelTests(TestCase): - def test_was_published_recently_with_future_question(self): """ was_published_recently() returns False for questions whose pub_date @@ -312,6 +311,7 @@ more comprehensively: old_question = Question(pub_date=time) self.assertIs(old_question.was_published_recently(), False) + def test_was_published_recently_with_recent_question(self): """ was_published_recently() returns True for questions whose pub_date @@ -393,7 +393,7 @@ With that ready, we can ask the client to do some work for us: .. code-block:: pycon >>> # get a response from '/' - >>> response = client.get('/') + >>> response = client.get("/") Not Found: / >>> # we should expect a 404 from that address; if you instead see an >>> # "Invalid HTTP_HOST header" error and a 400 response, you probably @@ -403,12 +403,12 @@ With that ready, we can ask the client to do some work for us: >>> # on the other hand we should expect to find something at '/polls/' >>> # we'll use 'reverse()' rather than a hardcoded URL >>> from django.urls import reverse - >>> response = client.get(reverse('polls:index')) + >>> response = client.get(reverse("polls:index")) >>> response.status_code 200 >>> response.content b'\n <ul>\n \n <li><a href="/polls/1/">What's up?</a></li>\n \n </ul>\n\n' - >>> response.context['latest_question_list'] + >>> response.context["latest_question_list"] <QuerySet [<Question: What's up?>]> Improving our view @@ -424,12 +424,12 @@ based on :class:`~django.views.generic.list.ListView`: :caption: ``polls/views.py`` class IndexView(generic.ListView): - template_name = 'polls/index.html' - context_object_name = 'latest_question_list' + template_name = "polls/index.html" + context_object_name = "latest_question_list" def get_queryset(self): """Return the last five published questions.""" - return Question.objects.order_by('-pub_date')[:5] + return Question.objects.order_by("-pub_date")[:5] We need to amend the ``get_queryset()`` method and change it so that it also checks the date by comparing it with ``timezone.now()``. First we need to add @@ -450,9 +450,9 @@ and then we must amend the ``get_queryset`` method like so: Return the last five published questions (not including those set to be published in the future). """ - return Question.objects.filter( - pub_date__lte=timezone.now() - ).order_by('-pub_date')[:5] + return Question.objects.filter(pub_date__lte=timezone.now()).order_by("-pub_date")[ + :5 + ] ``Question.objects.filter(pub_date__lte=timezone.now())`` returns a queryset containing ``Question``\s whose ``pub_date`` is less than or equal to - that @@ -496,10 +496,10 @@ class: """ If no questions exist, an appropriate message is displayed. """ - response = self.client.get(reverse('polls:index')) + response = self.client.get(reverse("polls:index")) self.assertEqual(response.status_code, 200) self.assertContains(response, "No polls are available.") - self.assertQuerySetEqual(response.context['latest_question_list'], []) + self.assertQuerySetEqual(response.context["latest_question_list"], []) def test_past_question(self): """ @@ -507,9 +507,9 @@ class: index page. """ question = create_question(question_text="Past question.", days=-30) - response = self.client.get(reverse('polls:index')) + response = self.client.get(reverse("polls:index")) self.assertQuerySetEqual( - response.context['latest_question_list'], + response.context["latest_question_list"], [question], ) @@ -519,9 +519,9 @@ class: the index page. """ create_question(question_text="Future question.", days=30) - response = self.client.get(reverse('polls:index')) + response = self.client.get(reverse("polls:index")) self.assertContains(response, "No polls are available.") - self.assertQuerySetEqual(response.context['latest_question_list'], []) + self.assertQuerySetEqual(response.context["latest_question_list"], []) def test_future_question_and_past_question(self): """ @@ -530,9 +530,9 @@ class: """ question = create_question(question_text="Past question.", days=-30) create_question(question_text="Future question.", days=30) - response = self.client.get(reverse('polls:index')) + response = self.client.get(reverse("polls:index")) self.assertQuerySetEqual( - response.context['latest_question_list'], + response.context["latest_question_list"], [question], ) @@ -542,9 +542,9 @@ class: """ question1 = create_question(question_text="Past question 1.", days=-30) question2 = create_question(question_text="Past question 2.", days=-5) - response = self.client.get(reverse('polls:index')) + response = self.client.get(reverse("polls:index")) self.assertQuerySetEqual( - response.context['latest_question_list'], + response.context["latest_question_list"], [question2, question1], ) @@ -584,6 +584,7 @@ we need to add a similar constraint to ``DetailView``: class DetailView(generic.DetailView): ... + def get_queryset(self): """ Excludes any questions that aren't published yet. @@ -603,8 +604,8 @@ is not: The detail view of a question with a pub_date in the future returns a 404 not found. """ - future_question = create_question(question_text='Future question.', days=5) - url = reverse('polls:detail', args=(future_question.id,)) + future_question = create_question(question_text="Future question.", days=5) + url = reverse("polls:detail", args=(future_question.id,)) response = self.client.get(url) self.assertEqual(response.status_code, 404) @@ -613,8 +614,8 @@ is not: The detail view of a question with a pub_date in the past displays the question's text. """ - past_question = create_question(question_text='Past Question.', days=-5) - url = reverse('polls:detail', args=(past_question.id,)) + past_question = create_question(question_text="Past Question.", days=-5) + url = reverse("polls:detail", args=(past_question.id,)) response = self.client.get(url) self.assertContains(response, past_question.question_text) diff --git a/docs/intro/tutorial07.txt b/docs/intro/tutorial07.txt index 14548590b3..71c13180fe 100644 --- a/docs/intro/tutorial07.txt +++ b/docs/intro/tutorial07.txt @@ -32,7 +32,8 @@ the ``admin.site.register(Question)`` line with: class QuestionAdmin(admin.ModelAdmin): - fields = ['pub_date', 'question_text'] + fields = ["pub_date", "question_text"] + admin.site.register(Question, QuestionAdmin) @@ -62,10 +63,11 @@ up into fieldsets: class QuestionAdmin(admin.ModelAdmin): fieldsets = [ - (None, {'fields': ['question_text']}), - ('Date information', {'fields': ['pub_date']}), + (None, {"fields": ["question_text"]}), + ("Date information", {"fields": ["pub_date"]}), ] + admin.site.register(Question, QuestionAdmin) The first element of each tuple in @@ -92,6 +94,7 @@ with the admin just as we did with ``Question``: from django.contrib import admin from .models import Choice, Question + # ... admin.site.register(Choice) @@ -135,11 +138,12 @@ registration code to read: class QuestionAdmin(admin.ModelAdmin): fieldsets = [ - (None, {'fields': ['question_text']}), - ('Date information', {'fields': ['pub_date'], 'classes': ['collapse']}), + (None, {"fields": ["question_text"]}), + ("Date information", {"fields": ["pub_date"], "classes": ["collapse"]}), ] inlines = [ChoiceInline] + admin.site.register(Question, QuestionAdmin) This tells Django: "``Choice`` objects are edited on the ``Question`` admin page. By @@ -204,7 +208,7 @@ object: class QuestionAdmin(admin.ModelAdmin): # ... - list_display = ['question_text', 'pub_date'] + list_display = ["question_text", "pub_date"] For good measure, let's also include the ``was_published_recently()`` method from :doc:`Tutorial 2 </intro/tutorial02>`: @@ -214,7 +218,7 @@ from :doc:`Tutorial 2 </intro/tutorial02>`: class QuestionAdmin(admin.ModelAdmin): # ... - list_display = ['question_text', 'pub_date', 'was_published_recently'] + list_display = ["question_text", "pub_date", "was_published_recently"] Now the question change list page looks like this: @@ -236,12 +240,13 @@ decorator on that method (in :file:`polls/models.py`), as follows: from django.contrib import admin + class Question(models.Model): # ... @admin.display( boolean=True, - ordering='pub_date', - description='Published recently?', + ordering="pub_date", + description="Published recently?", ) def was_published_recently(self): now = timezone.now() @@ -255,7 +260,7 @@ Edit your :file:`polls/admin.py` file again and add an improvement to the :attr:`~django.contrib.admin.ModelAdmin.list_filter`. Add the following line to ``QuestionAdmin``:: - list_filter = ['pub_date'] + list_filter = ["pub_date"] That adds a "Filter" sidebar that lets people filter the change list by the ``pub_date`` field: @@ -270,7 +275,7 @@ knows to give appropriate filter options: "Any date", "Today", "Past 7 days", This is shaping up well. Let's add some search capability:: - search_fields = ['question_text'] + search_fields = ["question_text"] That adds a search box at the top of the change list. When somebody enters search terms, Django will search the ``question_text`` field. You can use as many @@ -314,15 +319,15 @@ Open your settings file (:file:`mysite/settings.py`, remember) and add a TEMPLATES = [ { - 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'DIRS': [BASE_DIR / 'templates'], - 'APP_DIRS': True, - 'OPTIONS': { - 'context_processors': [ - 'django.template.context_processors.debug', - 'django.template.context_processors.request', - 'django.contrib.auth.context_processors.auth', - 'django.contrib.messages.context_processors.messages', + "BACKEND": "django.template.backends.django.DjangoTemplates", + "DIRS": [BASE_DIR / "templates"], + "APP_DIRS": True, + "OPTIONS": { + "context_processors": [ + "django.template.context_processors.debug", + "django.template.context_processors.request", + "django.contrib.auth.context_processors.auth", + "django.contrib.messages.context_processors.messages", ], }, }, |
