为何打不开中国建设银行网站,淘宝网站建设,网站备案哪里管,东莞网站排名优化Django从入门到放弃 Django最初被设计用于具有快速开发需求的新闻类站点#xff0c;目的是实现简单快捷的网站开发。 安装Django
使用anaconda创建环境
conda create -n django_env python3.10
conda activate django_env使用pip安装django
python -m pip install Django查…Django从入门到放弃 Django最初被设计用于具有快速开发需求的新闻类站点目的是实现简单快捷的网站开发。 安装Django
使用anaconda创建环境
conda create -n django_env python3.10
conda activate django_env使用pip安装django
python -m pip install Django查看安装的django版本
pythonimport djangoprint(django.get_version())
5.0.1编写你的第一个Django应用 创建一个基本的投票应用程序由两部分组成一个让人们查看和投票的公共站点一个让你能添加、修改和删除投票的管理站点。 创建项目
# 在当前目录下创建一个mysite目录
django-admin startproject mysite切换到mysite目录启动django开发服务器这个服务器不要用于生产
# 默认8000端口会自动重新加载的服务器runserver
python manage.py runserver
# 更换端口
python manage.py runserver 8080创建投票应用 在 Django 中每一个应用都是一个 Python 包并且遵循着相同的约定。Django 自带一个工具可以帮你生成应用的基础目录结构这样你就能专心写代码而不是创建目录了。 应用是一个专门做某件事的网络应用程序——比如博客系统或者公共记录的数据库或者小型的投票程序。项目则是一个网站使用的配置和应用的集合。项目可以包含很多个应用。应用可以被很多个项目使用。 python manage.py startapp polls编写第一个视图
1打开polls/views.py添加以下代码。
from django.shortcuts import render
from django.http import HttpResponsedef index(request):return HttpResponse(Hello, world. Youre at the polls index.)2在polls目录中创建一个URL配置创建urls.py添加以下代码。
from django.urls import path
from . import viewsurlpatterns [path(, views.index, nameindex),
]3在根URLconf文件中指定创建的polls.urls模块在mysite/urls.py文件中添加以下代码。
from django.contrib import admin
from django.urls import path, includeurlpatterns [# include允许引用其他URLConfspath(polls/, include(polls.urls)),path(admin/, admin.site.urls),
]4函数path有四个参数两个必传参数route和view两个可选参数kwargs和name。
routeroute是一个匹配URL的准则类似正则表达式。当Django响应一个请求时它会从urlpatterns的第一项开始按顺序依次匹配列表中的项直到找到匹配的项。这些准则不会匹配GET和POST参数或域名。view当Django找到了一个匹配的准则就会调用这个特定的视图函数并传入HttpRequest对象作为第一个参数被捕获的参数以关键词参数的形式传入。kwarg任意个关键词参数可以作为一个字典传递给目标视图函数。name为你的URL取名能使你在Django的任意地方唯一地引用它。
数据库配置
1打开mysite/setting.py该配置包含了Django项目设置的Python模块。
通常配置文件使用SQLite作为默认数据库。
DATABASES {default: {# ENGINE的可选值django.db.backends.sqlite3django.db.backends.postgresql# django.db.backends.mysql或 django.db.backends.oracleENGINE: django.db.backends.sqlite3,# NAME是数据库名称如果使用SQLite就是文件的完整的绝对路径# 如果不适用SQLite需要添加USER、PASSWORD、HOST等NAME: BASE_DIR / db.sqlite3,}
}如果使用SQLite以外的数据库确认在使用前已经创建了数据库。
2设置TIME_ZONE为自己的时区。
LANGUAGE_CODE zh-hans
TIME_ZONE Asia/Shanghai3设置应用默认开启的应用需要至少一个数据表使用前需要创建一些表
# 这个 migrate 命令查看 INSTALLED_APPS 配置并根据 mysite/settings.py 文件中的数据库配置和随应用提供的数据库迁移文件创建任何必要的数据库表。你会看到它应用的每一个迁移都有一个消息。
python manage.py migrateINSTALLED_APPS [# 默认包含了以下自带应用 # 管理员站点django.contrib.admin,# 认证授权系统django.contrib.auth,# 内容类型框架django.contrib.contenttypes,# 会话框架django.contrib.sessions,# 消息框架django.contrib.messages,# 管理静态文件的框架django.contrib.staticfiles, # 添加应用配置polls.apps.PollsConfig,
]模型
1一个模型就是单个定义你的数据的信息源。模型中包含了不可缺少的数据区域和你存储数据的行为。
2创建两个模型 问题Question包括问题描述和发布时间 选项Choice包括选项描述和当前得票数。 打开polls/models.py文件添加以下内容。
import datetime
from django.db import models
from django.utils import timezone# 每个模型都是django.db.models.Model类的子类
class Question(models.Model):# 模型的变量表示一个数据库字段每个字段都是Field类的实例# question_text也是字段名question_text models.CharField(max_length200)pub_date models.DateTimeField(date published)def __str__(self):return self.question_textdef was_published_recently(self):return self.pub_date timezone.now() - datetime.timedelta(days1)class Choice(models.Model):question models.ForeignKey(Question, on_deletemodels.CASCADE)choice_text models.CharField(max_length200)votes models.IntegerField(default0)def __str__(self):return self.choice_text3激活模型 首先把polls应用安装到我们的项目里。在INSTALLED_APPS中添加配置。因为PollConfig类写在文件polls/apps.py中所以它的路径是’polls.apps.PollsConfig’。 # 通过运行 makemigrations 命令Django 会检测你对模型文件的修改并且把修改的部分储存为一次迁移。
# migrate是自动执行数据库迁移并同步管理你的数据库结构的命令。
python manage.py makemigrations polls
# 查看迁移命令会执行哪些SQL语句
# 主键id会被自动创建也可以自定义数据库表名由应用名polls和模型名如question连接而来
# 默认Django会在外键字段名后追加字符串_id
python manage.py sqlmigrate polls 0001
# 检查项目中的问题
python manage.py check
# 再次运行migrate在数据库里创建新定义的模型的数据表
python manage.py migrate初始API
1进入交互式Python命令行
# 我们使用这个命令而不是简单的使用“python”是因为 manage.py 会设置 DJANGO_SETTINGS_MODULE 环境变量这个变量会让 Django 根据 mysite/settings.py 文件来设置 Python 包的导入路径。
python manage.py shell# 进入shell后就可以探索数据库APIfrom polls.models import Choice, QuestionQuestion.objects.all()from django.utils import timezone
# 添加记录q Question(question_textWhats new?, pub_datetimezone.now())q.save()q.id q.question_textq.pub_date
# 修改字段值q.question_text Whats up?q.save()
# 关键词查找Question.objects.filter(id1)Question.objects.filter(question_text__startswithWhat)
# 获取今年发布的问题from django.utils import timezonecurrent_year timezone.now().yearQuestion.objects.get(pub_date__yearcurrent_year)
# 请求不存在的记录会抛出一个异常Question.objects.get(id2)
# 查找主键值Question.objects.get(pk1)q Question.objects.get(pk1)q.was_published_recently()q.choice_set.all()
# 创建三个选项q.choice_set.create(choice_textNot much, votes0)q.choice_set.create(choice_textThe sky, votes0)c q.choice_set.create(choice_textJust hacking again, votes0)c.questionq.choice_set.count()
# 删除选项c q.choice_set.filter(choice_text__startswithJust hacking)c.delete()Django管理界面
1创建一个管理员账号
# 创建一个能登录管理页面的用户添加用户admin/admin
python manage.py createsuperuser2启动开发服务器 Django的管理界面默认就是启用的启动开发服务器访问/admin/目录。 3向管理界面中加入投票应用
# 打开polls/admin.py
from django.contrib import admin
from .models import Questionadmin.site.register(Question)视图 Django中的视图是一类具有相同功能和模板的网页的集合。网页和其他内容都是从视图派生而来。每个视图表现为一个Python函数会根据用户请求的URL来选择使用哪个视图。 1投票应用中需要的视图
问题索引页——展示最近的几个投票问题。问题详情页——展示某个投票的问题和不带结果的选项列表。问题结果页——展示某个投票的结果。投票处理器——用于响应用户为某个问题的特定选项投票的操作。
2URLconf将URL模式映射到视图
3编写更多的视图
# 向polls/views.py中添加更多视图
def detail(request, question_id):return HttpResponse(Youre looking at question %s. % question_id)def results(request, question_id):response Youre looking at the results of question %s.return HttpResponse(response % question_id)def vote(request, question_id):return HttpResponse(Youre voting on question %s. % question_id)# 把新视图加入到polls/urls.py文件
urlpatterns [path(, views.index, nameindex),# 使用尖括号获得网址部分后发送给视图函数作为一个关键字参数# question_id部分定义了要使用的名字用来识别相匹配的模式# int部分是一种转换形式用来确定应该匹配网址路径的什么模式# 冒号用来分隔转换形式和模式名path(int:question_id/, views.detail, namedetail),path(int:question_id/results/, views.results, nameresults),path(int:question_id/vote/, views.vote, namevote),
]4重构index方法 每个视图必须要要做的只有两个事情返回一个包含被请求页面内容的HttpResponse对象或者抛出一个异常。 from django.shortcuts import render
from .models import Question# Create your views here.
from django.http import HttpResponse
# 展示数据库里以发布日期排序的最近5个投票问题
def index(request):latest_question_list Question.objects.order_by(-pub_date)[:5]output , .join([q.question_text for q in latest_question_list]) return HttpResponse(output)def detail(request, question_id):return HttpResponse(Youre looking at question %s. % question_id)def results(request, question_id):response Youre looking at the results of question %s.return HttpResponse(response % question_id)def vote(request, question_id):return HttpResponse(Youre voting on question %s. % question_id)5使用Django的模板系统 在polls目录里新建一个templates目录TEMPLATES配置项描述了如何载入和渲染模板。默认的设置文件设置了DjangoTemplates后端并将APP_DIRS设置为True。这一选项将会让 DjangoTemplates 在每个 INSTALLED_APPS 文件夹中寻找 “templates” 子目录。在你刚刚创建的 templates 目录里再创建一个目录 polls然后在其中新建一个文件 index.html 。换句话说你的模板文件的路径应该是 polls/templates/polls/index.html 。因为app_directories 模板加载器是通过上述描述的方法运行的所以 Django 可以引用到 polls/index.html 这一模板了。 # polls/settings.py
TEMPLATES [{BACKEND: django.template.backends.django.DjangoTemplates,DIRS: [],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,],},},
]!-- polls/templates/polls/index.html --
{% if latest_question_list %}ul{% for question in latest_question_list %}!-- 硬编码连接 --!-- lia href/polls/{{ question.id }}/{{ question.question_text }}/a/li --!-- 在polls.urls模块的URL定义中寻具有指定名字的条目 --lia href{% url detail question.id %}{{ question.question_text }}/a/li{% endfor %}/ul
{% else %}pNo polls are available./p
{% endif %}# 更新index视图
from django.template import loader# 载入模板文件并传递一个上下文
def index(request):latest_question_list Question.objects.order_by(-pub_date)[:5]template loader.get_template(polls/index.html)context {latest_question_list: latest_question_list}return HttpResponse(template.render(context, request))6快捷函数render render函数载入模板填充上下文再返回由它生成的HttpResponse对象。 # 更新index视图我们不在需要导入loader和HttpResponse
from django.shortcuts import render
from .models import Questiondef 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)7抛出404错误
# 更新detail视图
from django.http import Http404
from django.shortcuts import render
from .models import Questiondef detail(request, question_id):try:question Question.objects.get(pkquestion_id)except Question.DoesNotExist:raise Http404(Question does not exist)return render(request, polls/detail.html, {question:question})!-- polls/templates/polls/detail.html --
!-- 模板系统使用点符号访问变量的属性 --
h1{{ question.question_text }}/h1
ul
{% for choice in question.choice_set.all %}li{{ choice.choice_text }}/li
{% endfor %}
/ul8快捷函数get_object_or_404
from django.shortcuts import render, get_object_or_404
# 更新detail视图
def detail(request, question_id):question get_object_or_404(Question, pkquestion_id)return render(request, polls/detail.html, {question:question})9为URL名称添加命名空间
# 在根URLconf中添加命名空间修改polls/urls.py
from django.urls import path
from . import viewsapp_name polls
urlpatterns [path(, views.index, nameindex),path(int:question_id/, views.detail, namedetail),path(int:question_id/results/, views.results, nameresults),path(int:question_id/vote/, views.vote, namevote),
]!-- polls/templates/polls/index.html --
lia href{% url polls:detail question.id %}{{ question.question_text }}/a/li表单处理
1编写一个简单的表单
!-- 更新polls/detail.html模板 --
form action{% url polls:vote question.id %} methodpost
!-- 防止跨站请求伪造 --
{% csrf_token %}
fieldsetlegendh1{{ question.question_text }}/h1/legend{% if error_message %}pstrong{{ error_message }}/strong/p{% endif %}{% for choice in question.choice_set.all %}!-- 在每个选项前加上一个单选按钮value属性对应选项的ID --!-- 当有人选择一个单选按钮并提交表单会发送一个POST数据choiceID --!-- forloop.counter指示for标签已经循环多少次 --input typeradio namechoice idchoice{{ forloop.counter }} value{{ choice.id }}label forchoice{{ forloop.counter }}{{ choice.choice_text }}/labelbr{% endfor %}
/fieldset
input typesubmit value投票
/form2更新vote和result视图
# polls/views.py
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render, get_object_or_404
from django.urls import reverse
from .models import Question, Choice def vote(request, question_id):question get_object_or_404(Question, pkquestion_id)try: # request.POST是一个类字典对象通过关键字的名字获取提交的字符串数据 selected_choice question.choice_set.get(pkrequest.POST[choice])except (KeyError, Choice.DoesNotExist):return render(request, polls/detail.html, {question:question,error_message:You didnt select a choice.})else:selected_choice.votes 1selected_choice.save()# 增加选项的投票后重定向到结果页# reverse函数避免在视图函数中硬编码URL需要传递的是要跳转的视图名字和参数return HttpResponseRedirect(reverse(polls:results, args(question.id,))) def results(request, question_id):question get_object_or_404(Question, pkquestion_id)return render(request, polls/results.html, {question:question}) 3创建一个结果页面
!-- polls/results.html --
h1{{ question.question_text }}/h1
ul
{% for choice in question.choice_set.all %}li{{ choice.choice_text }} -- {{ choice.votes }} vote{{ choice.votes|pluralize }}/li
{% endfor %}
/ul
a href{% url polls:detail question.id %}Vote again?/a4使用通用视图精简代码
转换URLconf删除一些旧的、不再需要的视图基于Django的通用视图引入新的视图。
5改良URLconf
# polls/urls.py
from django.urls import path
from . import viewsapp_name polls
urlpatterns [path(, views.IndexView.as_view(), nameindex),path(int:pk/, views.DetailView.as_view(), namedetail),path(int:pk/results/, views.ResultsView.as_view(), nameresults),path(int:question_id/vote/, views.vote, namevote),
]6改良视图
# polls/views.py
from django.http import HttpResponseRedirect
from django.shortcuts import render, get_object_or_404
from django.urls import reverse
from django.views import generic
from .models import Question, Choice class IndexView(generic.ListView):template_name polls/index.html# 替代默认提供的对象context_object_name latest_question_listdef get_queryset(self):return Question.objects.order_by(-pub_date)[:5] class DetailView(generic.DetailView):# 每个通用模型都需要知道它要操作的模型# 通过model属性提供这个信息或者定义get_queryset()方法来实现model Question# 默认情况下DetailView会使用app name/model name_detail.html的模板# template_name属性是用来告诉Django使用一个指定的模板名字而不是自动生成的默认名字template_name polls/detail.htmlclass ResultsView(generic.DetailView):model Questiontemplate_name polls/results.htmldef vote(request, question_id):question get_object_or_404(Question, pkquestion_id)try: selected_choice question.choice_set.get(pkrequest.POST[choice])except (KeyError, Choice.DoesNotExist):return render(request, polls/detail.html, {question:question,error_message:You didnt select a choice.})else:selected_choice.votes 1selected_choice.save()return HttpResponseRedirect(reverse(polls:results, args(question.id,)))自动化测试 测试代码是用来检查你的代码是否能够正常运行的程序。测试在不同的层次中都存在。自动化测试是由某个系统帮你自动完成的。当你创建好了一系列测试每次修改应用代码后就可以自动检查出修改后的代码是否还像你曾经预期的那样正常工作。你不需要花费大量时间来进行手动测试。 1为什么你需要写测试
测试帮你节约你的时间测试不仅能发现错误而且能够预防错误测试使你的代码更有吸引力测试有利于团队协作。
2基础测试策略 一些开发者遵循“测试驱动”的开发原则他们在写代码之前先写测试。 3开始写一个测试 我们的 polls 应用现在就有一个小 bug 需要被修复我们的要求是如果 Question 是在一天之内发布的 Question.was_published_recently() 方法将会返回 True 然而现在这个方法在 Question 的 pub_date 字段比当前时间还晚时也会返回 True。 # 打开shell查看这个问题
python manage.py shellimport datetimefrom django.utils import timezonefrom polls.models import Questionfuture_question Question(pub_datetimezone.now() datetime.timedelta(days30))future_question.was_published_recently()
True# 测试需要写在polls/tests.py中测试系统会自动寻找以test开头的测试函数并执行
import datetime
import datetime
from django.test import TestCase
from django.utils import timezone
from .models import Questionclass QuestionModelTests(TestCase):def test_was_published_recently_with_future_question(self):time timezone.now() datetime.timedelta(days30)future_question Question(pub_datetime)self.assertIs(future_question.was_published_recently(), False)# 在终端运行测试会自动寻找polls应用中的测试代码找到TestCase的子类创建一个特殊的数据库供测试使用寻找类中的test开头的方法执行
python manage.py test polls# 修复这个问题更新models.py中方法后再次运行测试问题解决
def was_published_recently(self):now timezone.now()return now - datetime.timedelta(days1) self.pub_date now4测试视图 Django提供了一个供测试使用的Client来模拟用户和视图层代码的交互。 # setup_test_environment()安装了一个模板渲染器使我们能够检查响应上的一些额外属性from django.test.utils import setup_test_environmentsetup_test_environment()
# 导入测试客户端类from django.test import Clientclient Client()
# 获取/的响应response client.get(/)response.status_code
404from django.urls import reverseresponse client.get(reverse(polls:index))response.status_code
200response.contentresponse.context[latest_question_list]from django.utils import timezone
# 更新ListView视图类
class IndexView(generic.ListView):template_name polls/index.htmlcontext_object_name latest_question_listdef get_queryset(self):return Question.objects.filter(pub_date__ltetimezone.now()).order_by(-pub_date)[:5]# 更新polls/tests.py
import datetime
from django.test import TestCase
from django.utils import timezone
from .models import Question
from django.urls import reverse# 封装了创建投票的流程减少了重复代码
def create_question(question_text, days):time timezone.now() datetime.timedelta(daysdays)return Question.objects.create(question_textquestion_text, pub_datetime)class QuestionIndexViewTests(TestCase):def test_no_questions(self):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], [])def test_past_question(self): question create_question(question_textPast question., days-30)response self.client.get(reverse(polls:index))self.assertQuerySetEqual(response.context[latest_question_list],[question],)class QuestionModelTests(TestCase):def test_was_published_recently_with_future_question(self):time timezone.now() datetime.timedelta(days30)future_question Question(pub_datetime)self.assertIs(future_question.was_published_recently(), False)# 更新DetailView视图排除还未发布的问题
class DetailView(generic.DetailView):model Questiontemplate_name polls/detail.htmldef get_queryset(self):return Question.objects.filter(pub_date__ltetimezone.now())添加样式表和图像
1自定义应用的界面和风格 在polls目录下新建static目录Django将在该目录下查找静态文件。Django 的 STATICFILES_FINDERS 设置包含了一系列的查找器它们知道去哪里找到static文件。AppDirectoriesFinder 是默认查找器中的一个它会在每个 INSTALLED_APPS中指定的应用的子文件中寻找名称为 static 的特定文件夹就像我们在 polls 中刚创建的那个一样。管理后台采用相同的目录结构管理它的静态文件。 /* 在polls目录下创建static目录,在创建polls目录然后添加style.css样式表polls/static/polls/style.css */
li a {color: green;
}!-- 在polls/templates/polls/index.html中添加样式表 --
!-- static模板标签生成静态文件的绝对路径 --
{% load static %}
link relstylesheet href{% static polls/style.css %}2添加背景图 在 polls/static/polls/ 目录中创建 images 子目录。 在此目录中添加您想用作背景的任何图像文件。 Django自动生成的后台
1自定义后台表单 通过 admin.site.register(Question) 注册 Question 模型Django 能够构建一个默认的表单用于展示。通常来说你期望能自定义表单的外观和工作方式。你可以在注册模型时将这些设置告诉 Django。 # polls/admin.py
from django.contrib import admin
from .models import Questionclass QuestionAdmin(admin.ModelAdmin):fields [pub_date, question_text]
# 创建一个模型后台类接着将其作为第二个参数传递给函数
admin.site.register(Question, QuestionAdmin)# 将表单分为几个字段集
from django.contrib import admin
from .models import Questionclass QuestionAdmin(admin.ModelAdmin):fieldsets [# fieldsets元组第一个元素是字段集的标题(None, {fields: [question_text]}),(Date information, {fields: [pub_date]}),]admin.site.register(Question, QuestionAdmin)2添加关联的对象
向后台注册Choice在创建投票对象时直接添加好几个选项。
# polls/admin.py
from django.contrib import admin
from .models import Question, Choice# 使用admin.TabularInline可以使关联对象以一种表格的方式展示
class ChoiceInline(admin.StackedInline):model Choiceextra 3class QuestionAdmin(admin.ModelAdmin):fieldsets [(None, {fields: [question_text]}),(Date information, {fields: [pub_date]}),]inlines [ChoiceInline]admin.site.register(Question, QuestionAdmin)3自定义后台更改列表 默认情况下Django 显示每个对象的 str() 返回的值。但有时如果我们能够显示单个字段它会更有帮助。为此使用 list_display后台选项它是一个包含要显示的字段名的元组 # polls/admin.py
class QuestionAdmin(admin.ModelAdmin):class QuestionAdmin(admin.ModelAdmin):fieldsets [(None, {fields: [question_text]}),(Date information, {fields: [pub_date]}),]inlines [ChoiceInline]list_display [question_text, pub_date, was_published_recently]# 优化过滤器添加了一个过滤器侧边栏list_filter [pub_date]# 列表顶部添加搜索框search_fields [question_text]# polls/models.py
import datetime
from django.db import models
from django.utils import timezone
from django.contrib import adminclass Question(models.Model):question_text models.CharField(max_length200)pub_date models.DateTimeField(date published)def __str__(self):return self.question_text# 通过display装饰器给方法添加排序字段admin.display(booleanTrue,orderingpub_date,descriptionPublished recently?,)def was_published_recently(self):now timezone.now()return now - datetime.timedelta(days1) self.pub_date now4自定义后台界面和风格 在工程目录包含manage.py的那个文件夹内创建一个templates目录。 # mysite/settings.py中添加DIRS选项
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,],},},
]在templates目录中创建一个admin目录将默认的Django管理界面模板目录中的模板文件复制到该目录中(admin/base_site.html)。默认的 Django 管理界面模板目录位于 Django 源代码中django/contrib/admin/templates。 # 获取Django源码的位置
python -c import django;print(django.__path__)!-- 修改base_site.html内容 --
{% extends admin/base.html %}{% block title %}{% if subtitle %}{{ subtitle }} | {% endif %}{{ title }} | {{ site_title|default:_(Django site admin) }}{% endblock %}{% block branding %}
div idsite-namea href{% url admin:index %}Polls Administration/a/div
{% if user.is_anonymous %}{% include admin/color_theme_toggle.html %}
{% endif %}
{% endblock %}{% block nav-global %}{% endblock %}5自定义你应用的模板 DIRS默认是空的Django 是怎么找到默认的后台模板的因为 APP_DIRS 被置为 TrueDjango 会自动在每个应用包内递归查找 templates/ 子目录 6自定义后台主页 默认情况下它展示了所有配置在 INSTALLED_APPS中已通过后台应用注册按拼音排序的应用。你可能想对这个页面的布局做重大的修改。毕竟索引页是后台的重要页面它应该便于使用。需要自定义的模板是 admin/index.html。 使用第三方包 以Django Debug Toolbar为例。 1安装
python -m pip install django-debug-toolbar与 Django 集成的第三方包需要一些安装后的设置以将它们与你的项目整合在一起。通常你需要将包的 Django 应用程序添加到你的 INSTALLED_APPS设置中。有些包需要其他更改比如添加到你的 URL 配置urls.py中。 2安装其他第三方包 可以使用Django资源 Django Packages来查找更多的第三方包。