django 3.0 文档学习笔记
1异常处理
常规办法
try: question = Question.objects.get(pk = question_id) except Question.DoesNotExist: raise Http404("sorry no exist")
新写法
from django.shortcuts import render,get_object_or_404 question = get_object_or_404(Question,pk=question_id)
2页面渲染
return render(request,'app/index.html',{a':a})
3应用注册
INSTALLED_APPS = [ 'polls.apps.PollsConfig', ]
4 模板路径
模板文件的路径应该是 polls/templates/polls/index.html
。因为``app_directories`` 模板加载器是通过上述描述的方法运行的,所以Django可以引用到 polls/index.html
这一模板了。
虽然我们现在可以将模板文件直接放在 polls/templates
文件夹中(而不是再建立一个 polls
子文件夹),但是这样做不太好。Django 将会选择第一个匹配的模板文件,如果你有一个模板文件正好和另一个应用中的某个模板文件重名,Django 没有办法 区分 它们。我们需要帮助 Django 选择正确的模板,最好的方法就是把他们放入各自的 命名空间 中,也就是把这些模板放入一个和 自身 应用重名的子文件夹里。
5外键使用
两个模型Question Choice
>>> q = Question.objects.get(pk=1) # 显示另一个模型中相关的项目 >>> q.choice_set.all() # 创建相关项目 >>> q.choice_set.create(choice_text='Not much', votes=0) # 赋值给另一个对象 >>> c = q.choice_set.create(choice_text='Just hacking again', votes=0) # 访问相关属性 >>> c.question # 获取相关项目 >>> q.choice_set.all() # 统计数量 >>> q.choice_set.count() 3
大家使用 Django 创建模型的时候一定会经常使用 ForeignKey 来创建两个表格之间多对一的外键关系,例如B中有一个 models.ForeignKey(A) 。而当我们需要反向查询 A 中某个具体实例所关联的 B 时,可能会用到 A.B_set.all() 或 B.objects.filter(A) 这两种不同的方法。后者的效率好像要略高一些
6 URL name
<li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li> <li><a href="{% url 'detail' question.id%}">{{ question.question_text }}</a></li>
可以写成下方的简单形式,实现解耦
前提时定义 url时,增加了name属性
path('<int:question_id>/', views.detail, name='detail'),
url()
函数中通过 name 参数为 URL 定义了名字,你可以使用 {% url %}
标签代替它
这样方便后期修改URL格式
为URL添加命名空间,因为一个项目下不能的应用可能有相同的视图名称,比如 detail
在url文件中添加命名空间
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'), ]
html中的写法也应做出相应的调整
<li><a href="{% url 'detail' question.id %}">{{ question.question_text }}</a></li> #改为 <li><a href="{% url 'polls:detail' question.id %}">{{ question.question_text }}</a></li>
7 表单及for循环
{{ forloop.counter }}可以实现for循环的计数问题
表单中添加
{% csrf_token %}
题外:radio,添加统一的name,如
<input name='choice{{forloop.counter}}'>
8 得定向
from django.http import HttpResponse, HttpResponseRedirect return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))
HttpResponseRedirect
只接收一个参数:用户将要被重定向的 URL
在HttpResponseRedirect
的构造函数中使用reverse()
函数。这个函数避免了我们在视图函数中硬编码 URL。它需要我们给出我们想要跳转的视图的名字和该视图所对应的 URL 模式中需要给该视图提供的参数。
注意,之后的args需是一个可迭代对象,参数需加,
9 通用视图
- 转换 URLconf。
- 删除一些旧的、不再需要的视图。
- 基于 Django 的通用视图引入新的视图。
path('<int:pk>/', views.DetailView.as_view(), name='detail'), path('<int:pk>/result/', views.ResutlView.as_view(), name='result'), # path('<int:question_id>/detail', views.detail, name='index'), path('<int:question_id>/vote', views.vote, name='vote'),
DetailView
期望从 URL 中捕获名为"pk"
的主键值,所以我们为通用视图把question_id
改成pk
。
class IndexView(generic.ListView): template_name = 'polls/index.html' context_object_name = 'last_question_list' def get_queryset(self): return Question.objects.order_by('-pub_date')[:5] class DetailView(generic.DetailView): model = Question template_name = 'polls/detail.html' class ResutlView(generic.DetailView): model = Question template_name = 'polls/result.html'
重新定义原先的方法,改为基于类的视图,一般有ListView和DetailVIew
指定model 和tempate_name即可快速实现详细页和列表页
如有自定义,比例index中显示最新5条,则使用get_queryset方法,对指定的last_question_list进行赋值
10后台配置
class QuestionAdmin(admin.ModelAdmin): fields = ['pub_date', 'question_text'] admin.site.register(Question, QuestionAdmin)
你需要遵循以下流程——创建一个模型后台类,接着将其作为第二个参数传给 admin.site.register()
fields可以指定显示字段的前后顺序
class ChoiceInline(admin.StackedInline):
model = Choice
extra = 3
fieldsets = [ (None,{'fields':['question_text']}), ('Date infomation',{'fields':['pub_date'],'classes':['collapse']}) ]
使用fieldsets可以更好的控制后台编辑页面,如上的效果为
对时间进行了隐藏,原来的选项可以全部显示出来,同时提供3个额外的填空,用户呆以批量删除原先的,也可以自由扩展
再改为表格显示,减少占用太多的页长
class ChoiceInline(admin.TabularInline): model = Choice extra=3
models中可以对类视图中的方法在后台管理中进行修饰
was_published_recently.admin_order_field = 'pub_date' was_published_recently.boolean = True was_published_recently.short_description = 'Published recently?'
参见 list_display
。