1.python_2_unicode_compatible装饰器

from django.db import models
from django.utils.encoding import python_2_unicode_compatible @python_2_unicode_compatible # 当你想支持python2版本的时候才需要这个装饰器
class Question(models.Model):
# ...
def __str__(self): # 在python2版本中使用的是__unicode__
return self.question_text @python_2_unicode_compatible
class Choice(models.Model):
# ...
def __str__(self):
return self.choice_text

2.URLconf的命名空间 app_name

现实中很显然会有5个、10个、更多的app同时存在一个项目中。Django用URL name区分这些app之间的关系

from django.conf.urls import url
from . import views
app_name = 'polls' # 关键是这行
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^(?P<question_id>[0-9]+)/$', views.detail, name='detail'),
url(r'^(?P<question_id>[0-9]+)/results/$', views.results, name='results'),
url(r'^(?P<question_id>[0-9]+)/vote/$', views.vote, name='vote'),
] <li><a href="{% url 'polls:detail' question.id %}">{{ question.question_text }}</a></li>

3.404错误错误页

get_object_or_404() 替代get()

get_list_or_404() 替代filter()

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})

4.HttpResponseRedirect 当POST数据处理成功后,建议用此函数;

reverse 帮助我们避免在视图函数中硬编码URL;

from django.shortcuts import get_object_or_404, render
from django.http import HttpResponseRedirect, HttpResponse
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'])
except (KeyError, Choice.DoesNotExist):
# 发生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()
# 成功处理数据后,自动跳转到结果页面,防止用户连续多次提交。
# 例如'/polls/3/results/',其中的3是某个question.id的值。重定向后将进入polls:results对应的视图,并将question.id传递给它
return HttpResponseRedirect(reverse('polls:results', args=(question.id,))) from django.shortcuts import get_object_or_404, render
def results(request, question_id):
question = get_object_or_404(Question, pk=question_id)
return render(request, 'polls/results.html', {'question': question}) <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?</a>

5.查看一个包安装路径

python -c "import django; print(django.__path__)"

6.FileField upload_to

# upload_to参数也可以接收一个回调函数
# user_directory_path这种回调函数,必须接收两个参数,然后返回一个Unix风格的路径字符串。参数instace代表一个定义了FileField的模型的实例,说白了就是当前数据记录。filename是原本的文件名。
def user_directory_path(instance, filename):
#文件上传到MEDIA_ROOT/user_<id>/<filename>目录中
return 'user_{0}/{1}'.format(instance.user.id, filename) class MyModel(models.Model):
upload = models.FileField(upload_to=user_directory_path) class MyModel(models.Model):
# 文件被传至`MEDIA_ROOT/uploads`目录,MEDIA_ROOT由你在settings文件中设置
upload = models.FileField(upload_to='uploads/')
# 或者
# 被传到`MEDIA_ROOT/uploads/2015/01/30`目录,增加了一个时间划分
upload = models.FileField(upload_to='uploads/%Y/%m/%d/')

7.递归外键 self ,典型的例子就是评论系统!一条评论可以被很多人继续评论

class Comment(models.Model):
title = models.CharField(max_length=128)
text = models.TextField()
parent_comment = models.ForeignKey('self', on_delete=models.CASCADE)

8.on_delete

on_delete
当一个被外键关联的对象被删除时,Django将模仿on_delete参数定义的SQL约束执行相应操作。比如,你有一个可为空的外键,并且你想让它在关联的对象被删除时,自动设为null,可以如下定义:
user = models.ForeignKey(
User,
models.SET_NULL,
blank=True,
null=True,
)
该参数可选的值都内置在django.db.models中,包括:
CASCADE:模拟SQL语言中的ON DELETE CASCADE约束,将定义有外键的模型对象同时删除!(该操作为当前Django版本的默认操作!)
PROTECT:阻止上面的删除操作,但是弹出ProtectedError异常
SET_NULL:将外键字段设为null,只有当字段设置了null=True时,方可使用该值。
SET_DEFAULT:将外键字段设为默认值。只有当字段设置了default参数时,方可使用。
DO_NOTHING:什么也不做。
SET():设置为一个传递给SET()的值或者一个回调函数的返回值。注意大小写。

9.related_query_name

反向关联查询名。用于从目标模型反向过滤模型对象的名称。(过滤和查询在后续章节会介绍)

class Tag(models.Model):
article = models.ForeignKey(
Article,
on_delete=models.CASCADE,
related_name="tags",
related_query_name="tag", # 注意这一行
)
name = models.CharField(max_length=255) # 现在可以使用‘tag’作为查询名了
Article.objects.filter(tag__name="important")

10.through(定义中间表)

如果你想自定义多对多关系的那张额外的关联表,可以使用这个参数!参数的值为一个中间模型。

最常见的使用场景是你需要为多对多关系添加额外的数据,比如两个人建立QQ好友的时间。

通常情况下,这张表在数据库内的结构是这个样子的:

中间表的id列....模型对象的id列.....被关联对象的id列
# 各行数据

如果自定义中间表并添加时间字段,则在数据库内的表结构如下:

中间表的id列....模型对象的id列.....被关联对象的id列.....时间对象列
# 各行数据

看下面的例子:

from django.db import models

class Person(models.Model):
name = models.CharField(max_length=50) class Group(models.Model):
name = models.CharField(max_length=128)
members = models.ManyToManyField(
Person,
through='Membership', ## 自定义中间表
through_fields=('group', 'person'),
) class Membership(models.Model): # 这就是具体的中间表模型
group = models.ForeignKey(Group, on_delete=models.CASCADE)
person = models.ForeignKey(Person, on_delete=models.CASCADE)
inviter = models.ForeignKey(
Person,
on_delete=models.CASCADE,
related_name="membership_invites",
)
invite_reason = models.CharField(max_length=64)

上面的代码中,通过class Membership(models.Model)定义了一个新的模型,用来保存Person和Group模型的多对多关系,并且同时增加了‘邀请人’和‘邀请原因’的字段。

through参数在某些使用场景中是必须的,至关重要,请务必掌握!

through_fields

接着上面的例子。Membership模型中包含两个关联Person的外键,Django无法确定到底使用哪个作为和Group关联的对象。所以,在这个例子中,必须显式的指定through_fields参数,用于定义关系。

through_fields参数接收一个二元元组('field1', 'field2'),field1是指向定义有多对多关系的模型的外键字段的名称,这里是Membership中的‘group’字段(注意大小写),另外一个则是指向目标模型的外键字段的名称,这里是Membership中的‘person’,而不是‘inviter’。

再通俗的说,就是through_fields参数指定从中间表模型Membership中选择哪两个字段,作为关系连接字段。

11.自定义错误页面

  • handler400 —— django.conf.urls.handler400。
  • handler403 —— django.conf.urls.handler403。
  • handler404 —— django.conf.urls.handler404。
  • handler500 —— django.conf.urls.handler500。

首先,在根URLconf中额外增加下面的条目:

# 增加的条目
handler400 = views.bad_request
handler403 = views.permission_denied
handler404 = views.page_not_found
handler500 = views.page_error

然后在,views.py文件中增加四个处理视图:

def page_not_found(request):
return render(request, '404.html') def page_error(request):
return render(request, '500.html') def permission_denied(request):
return render(request, '403.html') def bad_request(request):
return render(request, '400.html') 注意:setttings 改成 DEBUG = False ALLOWED_HOSTS = ['*']

12.csv文件下载

import csv
from django.http import StreamingHttpResponse
class Echo(object):
"""An object that implements just the write method of the file-like
interface.
"""
def write(self, value):
"""Write the value by returning it, instead of storing in a buffer."""
return value def some_view(request):
# # Create the HttpResponse object with the appropriate CSV header.
response = HttpResponse(content_type='text/csv')
response['Content-Disposition'] = 'attachment; filename="somefilename.csv"' writer = csv.writer(response)
writer.writerow(['First row', 'Second row', 'Third row', 'Fourth row'])
rows = (["Row {}".format(idx), str(idx + 10), str(idx + 20), str(idx + 30)] for idx in range(65536))
for row in rows:
writer.writerow(row)
return response # rows = (["Row {}".format(idx), str(idx+10),str(idx+20),str(idx+30)] for idx in range(65536))
# pseudo_buffer = Echo()
# writer = csv.writer(pseudo_buffer)
# response = StreamingHttpResponse((writer.writerow(['First row', 'Second row', 'Third row', 'Fourth row'])),
# content_type="text/csv")
# response = StreamingHttpResponse((writer.writerow(row) for row in rows),
# content_type="text/csv")
# response['Content-Disposition'] = 'attachment; filename="somefilename.csv"'
# return response

13.

CP: http://www.liujiangblog.com/course/django/96

Django 拾遗的更多相关文章

  1. Django拾遗--pagination、sitemap、admin、form

    Django拾遗--pagination.sitemap.admin.form pagination 其实这个分页模块的原理就是根据设定的每页条数来分割queryset.查询结果/每页子项数目=页数 ...

  2. Python学习---Django拾遗180328

    Django之生命周期 前台发送URL请求到Django的中间件进行内容校验,完成校验后到达路由映射文件url.py,然后调用视图函数views.py里面的函数进行内容处理[ 1.操作数据库进行数据读 ...

  3. django请求生命周期,FBV和CBV,ORM拾遗,Git

    一.django 请求生命周期 流程图: 1. 当用户在浏览器中输入url时,浏览器会生成请求头和请求体发给服务端请求头和请求体中会包含浏览器的动作(action),这个动作通常为get或者post, ...

  4. python 全栈开发,Day84(django请求生命周期,FBV和CBV,ORM拾遗,Git)

    一.django 请求生命周期 流程图: 1. 当用户在浏览器中输入url时,浏览器会生成请求头和请求体发给服务端请求头和请求体中会包含浏览器的动作(action),这个动作通常为get或者post, ...

  5. Django之拾遗

    一.设计模式 1.1 MVC 模型(M)是数据的表述,非真正数据,而是数据接口. 视图(V)是你看到的界面,是模型的表现层,此外还提供了收集用户输入的接口. 控制器(C)控制模型和视图之间的信息流动. ...

  6. Python学习---Model拾遗[1]180318

    Model: 强大的数据库操作,弱小的数据验证 Form:  强大的数据验证 ModelForm: 强大的数据验证 + 弱小的数据库操作 Model拾遗 Model基本操作 1. 创建数据库表2. 修 ...

  7. django from表单基础知识点

    今日概要: - 内容拾遗 - 分页 - Form验证 1.内容拾遗 - 新URL -提交时,保留之前的内容? - 对话框 - var data = $('#fmForm表单的ID').serializ ...

  8. Django——form组件和ModelForm

    一.原生form实现书城增删改查 1.构建模型并完成数据库迁移 (1)构建书城模型 from django.db import models # Create your models here. # ...

  9. 基于Django框架 CRM的增删改查

    思路: 创建表------从数据库读出数据展示出来------配置路由-----写视图函数------写对应页面 练习点: 数据库建表 ORM 数据库数据读取 数据 ModelForm  (form组 ...

随机推荐

  1. Ajax 的学习

    (一)基础知识和新的概念      1,AJAX 就是浏览器提供的一套 API,可以通过 JavaScript 调用,从而实现通过代码控制请求与响应.实现 网络编程.   2,AJAX(Asynchr ...

  2. linux系统添加swap(虚拟内存)分区

    ​ 在实际的生产环境中,实际的物理内存我们经常会觉得不够用,增加物理内存的成本又比较高,一种折中方案就出来了,使用硬盘的一部分空间来做Swap(windows 下叫虚拟内存),将系统内非活动内存换页到 ...

  3. 51Node 1051---最大子矩阵和

    题目链接 一个M*N的矩阵,找到此矩阵的一个子矩阵,并且这个子矩阵的元素的和是最大的,输出这个最大的值.   例如:3*3的矩阵:   -1 3 -1 2 -1 3 -3 1 2   和最大的子矩阵是 ...

  4. Android应用系列:完美运行GIF格式的ImageView(附源码)

    前言 我们都知道ImageView是不能完美加载Gif格式的图片,如果我们在ImageView中src指定的资源是gif格式的话,我们将会惊喜的发觉画面永远停留在第一帧,也就是不会有动画效果.当然,经 ...

  5. SQL 必知必会·笔记<20>高级SQL特性

    1. 约束 约束(constraint)就是管理如何插入或处理数据库数据的规则.DBMS通过在数据库表上施加约束来实施引用完整性. 1.1 主键 主键是一种特殊的约束,用来保证一列(或一组列)中的值是 ...

  6. Java并发编程笔记之StampedLock锁源码探究

    StampedLock是JUC并发包里面JDK1.8版本新增的一个锁,该锁提供了三种模式的读写控制,当调用获取锁的系列函数的时候,会返回一个long 型的变量,该变量被称为戳记(stamp),这个戳记 ...

  7. ProxySQL 配置详解及读写分离(+GTID)等功能说明 (完整篇)

    ProxySQL是灵活强大的MySQL代理层, 是一个能实实在在用在生产环境的MySQL中间件,可以实现读写分离,支持 Query 路由功能,支持动态指定某个 SQL 进行 cache,支持动态加载配 ...

  8. SaltStack快速入门-配置管理

    1:定义远程配置时描述位置,salt配置用的是一种yaml的描述语法,saltstack也是可以分环境的,比如测试环境.生产环境,默认是base,base也是必须存在的,修改内容如下: file_ro ...

  9. Python机器学习笔记:深入理解Keras中序贯模型和函数模型

     先从sklearn说起吧,如果学习了sklearn的话,那么学习Keras相对来说比较容易.为什么这样说呢? 我们首先比较一下sklearn的机器学习大致使用流程和Keras的大致使用流程: skl ...

  10. 团队项目alpha冲刺

    Deadline: 2018-11-18 22:00PM,以博客提交至班级博客时间为准 提交: (a) 项目课堂演示: (b) 7篇冲刺随笔,组内可共享: (c) 1篇测试随笔,组内可共享: (d) ...