python Django后台开发笔记11
2016-02-25 23:49
826 查看
转载来自2014-12-01 21:35:59http://www.cnblogs.com/wupeiqi/p/4133236.html
1、回顾上周WSGI流程
看HttpServer的代码,画一个流程图
为什么开发时,我们不用这个框架呢?因为太单薄了,一切功能都需要自己去实现,所有的开发人员为了不让自己太疲惫,就转投使用一些web框架,也就是他们写图上的功能。好,既然说使用框架比我们自己写要方便,就来看看到方便在那里。
2、对比于自己的框架,我们来看一下Django框架是怎么会做和用的!
先画一个流程图
注意,我们的框架是 Application类的Runserver方法接收到wsgi的请求信息,然后返回了数据。
即然,之前一直说我们的框架和Django的框架本质上一样的,对不对,那么他肯定也有一个方法来接受 wsgi 的请求,然后再去执行一列后面的方法,然后给返回数据。这个方法就是 WSGIHandler 的 __call__ 方法,就是由它触发的整个执行过程。这里就是开始处理的源头。也就是,每次请求到来的时候,就会从这里开始去处理。
我们框架的起始点和Django的起始点都有,我们的框架是直接返回了数据,而Django又执行了一系列地方,再返回数据。我们就来看看这一列的方法中,都有那些功能,然后我们在一步步学习它。
就是在Django里,根据 url中的 模版去指定那个方法去处理请求。那Django是怎么找的呢?
开始写,登录:
几个重要的配置:
TEMPLATE_DIRS = (
os.path.join(BASE_DIR,'Templates'),
)
STATICFILES_DIRS =(
os.path.join(BASE_DIR,'Statics'),
)
普通URL,每个路由指定一个函数。如果新建一个函数,那就再创建URL进行指定。那么问题来了,我想要一个动态参数,创建一个程序,总不可能是1、2、3、4==》动态字段
URL里动态参数,利用正则表达式,(\w*),这样是不是就可以根据参数值,然后动态的去取数据了,那么问题又来了,如果我想要为我的参数设置一个默认值呢?
正则表达式的模版,(?P<name>\w*),在参数后面,针对name设置默认值
当你的App多了之后,URL的区分是不是很麻烦了,需要导入很多包,为了避免麻烦呢,我们使用 pattern 前缀来解决这个问题。
最后一个就是 include,就是把这个url前缀的所有东西,都交给另外一个url文件。
还有一种想法就是动态创建模块和执行方法
例子:根据id的不同,去获取不同的数据
经过以上的路由系统,就可以把请求转反给我们指定view中的函数去执行。也就是开始了MTV框架中的V来执行。那我们知道,V其实就是业务处理单元,所有的处理都离不开数据,v 通过 m 从数据库中获取数据,然后再嵌套到 t 中,最后返回给用户。
一般情况下,我们使用 MySQLdb 来连接数据库,首先我们需要创建数据库,然后设计表结构,表机构设计好之后,在程序中些sql语句,然后对数据进行操作。
对于Django来说,他没有什么特别的,其实最终他也是通过SQL和数据打交道,不同的是什么呢?就是Django在这里为我们做了一些事情,让我们操作比较便捷。
一般设计:
1、创建数据库,设计表结构和字段
2、编写数据访问层,对数据库进行操作。
3、业务逻辑层去调用并返回数据即可。
而对于Djanog呢,他为我们提供了一种关系对象映射,也叫 ORM,Hibernate 、activerecord,EF。他是个什么东西呢?
首先说,他是个什么? 他规定项目中的类对应数据库中的表,并且可以根据类去生成数据库表和字段,也称为code first
Django也为我提供这种功能,利用这个功能我们可以省去一般设计中的前两步,也就是表的设计和数据库访问层的创建。
一般的:
Django:创建类,然后只需要去继承 django.db.models.Model 类就可以了,我们在创建数据库的表的时候,是不会有一些一个数据类型、长度、能否为空、默认值、主键、外键需要我们去设置啊,Django的ORM需要代替我们去设置这些内容。想要在代码中创建不是一件很难的事情,只要让django代码和sql一一对应就好了。。。、
1、创建数据库结构:
外键: Color = models.ForeignKey(ColorDic)一对一: authors = models.OneToOneField(OneModel)
多对多:authors = models.ManyToManyField(Author)
参数
1.null=True
数据库中字段是否可以为空
2.blank=True
django的admin中添加数据时候是否可以为空
3、primary_key=False
主键,对AutoField设置主键后就会太低原来自增的ID列
4.auto_now和auto_now_add
auto_now 自动创建----无论添加或者修改,都是当前操作时间
auto_now_add 自动创建----永远是创建时的时间
5.choices
GENDER_CHOICE=(
(u'M',u'Male'),
(u'F',u'Female'),
)
6.max_length
7.default 默认值
8.verbose_name Admin中字段的显示名称
9.name|db_column 数据库中字段的名称
10.unique=True 不允许重复
11.db_index=True 数据库索引
12.editable=True 在Admin里是否可编辑
13.error_messages=None 提示错误
14.auto_created=False 自动创建
15.help_text 在admin中提示帮助信息
16.validators=[]
17.upload-to
2、执行SQL
增加:创建实例,并调用save
更新:a.获取实例,再sava;b.update(指定列)
删除:a. filter().delete(); b.all().delete()
获取:a. 单个=get(id=1) ;b. 所有 = all()
过滤:filter(name='xxx');filter(name__contains='');(id__in = [1,2,3]) ; icontains (大小写无关的 LIKE ), startswith 和 endswith , 还有 range (SQL BETWEEN 查询)
'gt', 'in', 'isnull', 'endswith', 'contains', 'lt', 'startswith', 'iendswith', 'icontains','range', 'istartswith'
排序:order_by("name") =asc ;order_by("-name")=desc
默认排序:class Meta: ordering = ['name']
返回第n-m条:第n条[0];前两条[0:2]
指定映射:values
数量:count()
聚合:from django.db.models import Min,Max,Sum objects.all().aggregate(Max('guest_id'))
原始SQL:
1、模版的创建过程,对于模版,其实就是读取模版(其中嵌套着模版标签),然后将 Model 中获取的数据插入到模版中,最后将信息返回给用户。
1
2
3
4
5
注意:当数据POST的时候,Django做了跨站请求伪造
2、模版语言:
{{ person_name }}
{{ ship_date|date:"F j, Y" }} 不建议
{{ bio|truncatewords:"30" }}
{{ my_list|first|upper }}
{{ name|lower }}
{% for item in item_list %} <li>{{ item }}</li> {% endfor %}
forloop.counter0
forloop.revcounter
forloop.revcounter0
forloop.first
forloop.last
forloop.parentloop
{% if ordered_warranty %}
{% if not ordered_warranty %}
{% include 'includes/nav.html' %} 包含标签
{% block title %}{% endblock %} {% extends "base.html" %} 模板
{# this is not a comment #} {% comment %}{% endcomment %}
{% ifequal user currentuser %} {% endifequal %}
3、Form
当执行is_valid()方法的时候,会根据定义的正则表达式,去匹配传入的值。
对于 form.as_table ,看一下源码,就知道他也很一般。我们自己也可以些一个。
扩展:根据自己的需求去定制html控件,如:分页。
需要创建超级用户:python manage.py createsuperuser
在模型部分已经有涉及到Admin方面的知识,Admin是一个Django提供给我们管理数据的页面,不用再去费劲的去写SQL语句,最开始创建的那些表,也是用于Admin的。
对于创站初期,admin还是很有用处的,每个App都有 admin.py 文件,这个文件连接了 APP 和 Admin
1、把模型注册到admin里才能使用: admin.site.register(Publisher)
2、Admin中表中每列的显示都是默认object,只有设置了 __unnicode__ 方法之后,即显示该返回值。
3、List中显示多列
list_display = ('id','Name',) --列表中显示的列
search_fields = ('id', 'Name') --搜索框
list_filter = ('Name',) --侧边过滤器
date_hierarchy = 'DataTime3' --时间下拉
ordering = ('-DataTime3',) --列表中的排序
fields = ('Name','DataTime1') --详细页面字段顺序
filter_horizontal = ('Name',) --显示多对多的关系
raw_id_fields = ('publisher',) --显示外键的数据
http://www.cnblogs.com/wupeiqi/diary/2014/11/10/4087669.html
不能让用户看见错误
1、回顾上周WSGI流程
看HttpServer的代码,画一个流程图
为什么开发时,我们不用这个框架呢?因为太单薄了,一切功能都需要自己去实现,所有的开发人员为了不让自己太疲惫,就转投使用一些web框架,也就是他们写图上的功能。好,既然说使用框架比我们自己写要方便,就来看看到方便在那里。
2、对比于自己的框架,我们来看一下Django框架是怎么会做和用的!
先画一个流程图
注意,我们的框架是 Application类的Runserver方法接收到wsgi的请求信息,然后返回了数据。
即然,之前一直说我们的框架和Django的框架本质上一样的,对不对,那么他肯定也有一个方法来接受 wsgi 的请求,然后再去执行一列后面的方法,然后给返回数据。这个方法就是 WSGIHandler 的 __call__ 方法,就是由它触发的整个执行过程。这里就是开始处理的源头。也就是,每次请求到来的时候,就会从这里开始去处理。
我们框架的起始点和Django的起始点都有,我们的框架是直接返回了数据,而Django又执行了一系列地方,再返回数据。我们就来看看这一列的方法中,都有那些功能,然后我们在一步步学习它。
一、路由系统
就是在Django里,根据 url中的 模版去指定那个方法去处理请求。那Django是怎么找的呢?开始写,登录:
几个重要的配置:
TEMPLATE_DIRS = (
os.path.join(BASE_DIR,'Templates'),
)
STATICFILES_DIRS =(
os.path.join(BASE_DIR,'Statics'),
)
普通URL,每个路由指定一个函数。如果新建一个函数,那就再创建URL进行指定。那么问题来了,我想要一个动态参数,创建一个程序,总不可能是1、2、3、4==》动态字段
URL里动态参数,利用正则表达式,(\w*),这样是不是就可以根据参数值,然后动态的去取数据了,那么问题又来了,如果我想要为我的参数设置一个默认值呢?
正则表达式的模版,(?P<name>\w*),在参数后面,针对name设置默认值
当你的App多了之后,URL的区分是不是很麻烦了,需要导入很多包,为了避免麻烦呢,我们使用 pattern 前缀来解决这个问题。
最后一个就是 include,就是把这个url前缀的所有东西,都交给另外一个url文件。
url(r'^first/hello/(\w*)/(\d*)',FirstView.Hello), url(r'^first/helloo/(?P<name>\w*)/(?P<id>\d*)',FirstView.Helloo), url(r'^first/helloo/(?P<name>\w*)',FirstView.Helloo,{'id':333}),
from django.conf.urls import patterns, include, url urlpatterns = patterns('', url(r'^admin/',include('AdminApp.urls')), url(r'^web/',include('WebApp.urls')), ) from django.conf.urls import patterns, include, url from AdminApp.Views.FirstView import Hello1 urlpatterns = patterns( '', url(r'^hello/$', Hello1), )
还有一种想法就是动态创建模块和执行方法
例子:根据id的不同,去获取不同的数据
经过以上的路由系统,就可以把请求转反给我们指定view中的函数去执行。也就是开始了MTV框架中的V来执行。那我们知道,V其实就是业务处理单元,所有的处理都离不开数据,v 通过 m 从数据库中获取数据,然后再嵌套到 t 中,最后返回给用户。
二、模型
一般情况下,我们使用 MySQLdb 来连接数据库,首先我们需要创建数据库,然后设计表结构,表机构设计好之后,在程序中些sql语句,然后对数据进行操作。对于Django来说,他没有什么特别的,其实最终他也是通过SQL和数据打交道,不同的是什么呢?就是Django在这里为我们做了一些事情,让我们操作比较便捷。
一般设计:
1、创建数据库,设计表结构和字段
2、编写数据访问层,对数据库进行操作。
3、业务逻辑层去调用并返回数据即可。
而对于Djanog呢,他为我们提供了一种关系对象映射,也叫 ORM,Hibernate 、activerecord,EF。他是个什么东西呢?
首先说,他是个什么? 他规定项目中的类对应数据库中的表,并且可以根据类去生成数据库表和字段,也称为code first
Django也为我提供这种功能,利用这个功能我们可以省去一般设计中的前两步,也就是表的设计和数据库访问层的创建。
一般的:
import MySQLdb def GetList(sql): db = MySQLdb.connect(user='root', db='wupeiqidb', passwd='1234', host='localhost') cursor = db.cursor() cursor.execute(sql) data = cursor.fetchall() db.close() return data def GetSingle(sql): db = MySQLdb.connect(user='root', db='wupeiqidb', passwd='1234', host='localhost') cursor = db.cursor() cursor.execute(sql) data = cursor.fetchone() db.close() return data
Django:创建类,然后只需要去继承 django.db.models.Model 类就可以了,我们在创建数据库的表的时候,是不会有一些一个数据类型、长度、能否为空、默认值、主键、外键需要我们去设置啊,Django的ORM需要代替我们去设置这些内容。想要在代码中创建不是一件很难的事情,只要让django代码和sql一一对应就好了。。。、
1、创建数据库结构:
1、models.AutoField 自增列 = int(11) 如果没有的话,默认会生成一个名称为 id 的列,如果要显示的自定义一个自增列,必须将给列设置为主键 primary_key=True。 2、models.CharField 字符串字段 必须 max_length 参数 3、models.BooleanField 布尔类型=tinyint(1) 不能为空,Blank=True 4、models.ComaSeparatedIntegerField 用逗号分割的数字=varchar 继承CharField,所以必须 max_lenght 参数 5、models.DateField 日期类型 date 对于参数,auto_now = True 则每次更新都会更新这个时间;auto_now_add 则只是第一次创建添加,之后的更新不再改变。 6、models.DateTimeField 日期类型 datetime 同DateField的参数 7、models.Decimal 十进制小数类型 = decimal 必须指定整数位max_digits和小数位decimal_places 8、models.EmailField 字符串类型(正则表达式邮箱) =varchar 对字符串进行正则表达式 9、models.FloatField 浮点类型 = double 10、models.IntegerField 整形 11、models.BigIntegerField 长整形 integer_field_ranges = { 'SmallIntegerField': (-32768, 32767), 'IntegerField': (-2147483648, 2147483647), 'BigIntegerField': (-9223372036854775808, 9223372036854775807), 'PositiveSmallIntegerField': (0, 32767), 'PositiveIntegerField': (0, 2147483647), } 12、models.IPAddressField 字符串类型(ip4正则表达式) 13、models.GenericIPAddressField 字符串类型(ip4和ip6是可选的) 参数protocol可以是:both、ipv4、ipv6 验证时,会根据设置报错 14、models.NullBooleanField 允许为空的布尔类型 15、models.PositiveIntegerFiel 正Integer 16、models.PositiveSmallIntegerField 正smallInteger 17、models.SlugField 减号、下划线、字母、数字 18、models.SmallIntegerField 数字 数据库中的字段有:tinyint、smallint、int、bigint 19、models.TextField 字符串=longtext 20、models.TimeField 时间 HH:MM[:ss[.uuuuuu]] 21、models.URLField 字符串,地址正则表达式 22、models.BinaryField 二进制 23、models.ImageField 图片 24、models.FilePathField 文件
外键: Color = models.ForeignKey(ColorDic)一对一: authors = models.OneToOneField(OneModel)
多对多:authors = models.ManyToManyField(Author)
def __unicode__(self): return self.name
参数
1.null=True
数据库中字段是否可以为空
2.blank=True
django的admin中添加数据时候是否可以为空
3、primary_key=False
主键,对AutoField设置主键后就会太低原来自增的ID列
4.auto_now和auto_now_add
auto_now 自动创建----无论添加或者修改,都是当前操作时间
auto_now_add 自动创建----永远是创建时的时间
5.choices
GENDER_CHOICE=(
(u'M',u'Male'),
(u'F',u'Female'),
)
6.max_length
7.default 默认值
8.verbose_name Admin中字段的显示名称
9.name|db_column 数据库中字段的名称
10.unique=True 不允许重复
11.db_index=True 数据库索引
12.editable=True 在Admin里是否可编辑
13.error_messages=None 提示错误
14.auto_created=False 自动创建
15.help_text 在admin中提示帮助信息
16.validators=[]
17.upload-to
2、执行SQL
增加:创建实例,并调用save
更新:a.获取实例,再sava;b.update(指定列)
删除:a. filter().delete(); b.all().delete()
获取:a. 单个=get(id=1) ;b. 所有 = all()
过滤:filter(name='xxx');filter(name__contains='');(id__in = [1,2,3]) ; icontains (大小写无关的 LIKE ), startswith 和 endswith , 还有 range (SQL BETWEEN 查询)
'gt', 'in', 'isnull', 'endswith', 'contains', 'lt', 'startswith', 'iendswith', 'icontains','range', 'istartswith'
排序:order_by("name") =asc ;order_by("-name")=desc
默认排序:class Meta: ordering = ['name']
返回第n-m条:第n条[0];前两条[0:2]
指定映射:values
数量:count()
聚合:from django.db.models import Min,Max,Sum objects.all().aggregate(Max('guest_id'))
原始SQL:
cursor = connection.cursor() cursor.execute('''SELECT DISTINCT first_name ROM people_person WHERE last_name = %s""", ['Lennon']) row = cursor.fetchone()
三、模版
1、模版的创建过程,对于模版,其实就是读取模版(其中嵌套着模版标签),然后将 Model 中获取的数据插入到模版中,最后将信息返回给用户。1
2
3
4
5
注意:当数据POST的时候,Django做了跨站请求伪造
2、模版语言:
{{ person_name }}
{{ ship_date|date:"F j, Y" }} 不建议
{{ bio|truncatewords:"30" }}
{{ my_list|first|upper }}
{{ name|lower }}
{% for item in item_list %} <li>{{ item }}</li> {% endfor %}
forloop.counter0
forloop.revcounter
forloop.revcounter0
forloop.first
forloop.last
forloop.parentloop
{% if ordered_warranty %}
{% if not ordered_warranty %}
{% include 'includes/nav.html' %} 包含标签
{% block title %}{% endblock %} {% extends "base.html" %} 模板
{# this is not a comment #} {% comment %}{% endcomment %}
{% ifequal user currentuser %} {% endifequal %}
3、Form
class ALogin(forms.Form): username = forms.CharField() email = forms.EmailField(required=True) ip = forms.IPAddressField()
def Login(request): if request.method == 'POST': form = ALogin(request.POST) if form.is_valid(): data = form.cleaned_data return HttpResponse("<h1>OK</h1>"); form = ALogin() #form = AccountForm(initial={'name': 'I love your site!'}) return render_to_response('Form/Login.html',{'form': form},context_instance=RequestContext(request))
当执行is_valid()方法的时候,会根据定义的正则表达式,去匹配传入的值。
对于 form.as_table ,看一下源码,就知道他也很一般。我们自己也可以些一个。
扩展:根据自己的需求去定制html控件,如:分页。
四、Admin
需要创建超级用户:python manage.py createsuperuser在模型部分已经有涉及到Admin方面的知识,Admin是一个Django提供给我们管理数据的页面,不用再去费劲的去写SQL语句,最开始创建的那些表,也是用于Admin的。
对于创站初期,admin还是很有用处的,每个App都有 admin.py 文件,这个文件连接了 APP 和 Admin
1、把模型注册到admin里才能使用: admin.site.register(Publisher)
2、Admin中表中每列的显示都是默认object,只有设置了 __unnicode__ 方法之后,即显示该返回值。
3、List中显示多列
class AuthorAdmin(admin.ModelAdmin): list_display = ('id','name',) def name(self, obj): return obj.Name admin.site.register(DateTimeArg,AuthorAdmin)
list_display = ('id','Name',) --列表中显示的列
search_fields = ('id', 'Name') --搜索框
list_filter = ('Name',) --侧边过滤器
date_hierarchy = 'DataTime3' --时间下拉
ordering = ('-DataTime3',) --列表中的排序
fields = ('Name','DataTime1') --详细页面字段顺序
filter_horizontal = ('Name',) --显示多对多的关系
raw_id_fields = ('publisher',) --显示外键的数据
五、中间件
http://www.cnblogs.com/wupeiqi/diary/2014/11/10/4087669.html
六、装饰器的应用
@Filter(AccountFilter.Before, AccountFilter.After) def Index(request,kargs): def Filter(before_func,after_func): def outer(main_func): def wrapper(request,kargs): before_result = before_func(request,kargs) if(before_result != None): return before_result; main_result = main_func(request,kargs) if(main_result != None): return main_result; after_result = after_func(request,kargs) if(after_result != None): return after_result; return wrapper return outer def Before(request,kargs): host = request.META if host == '127.0.0.1': return None else: #return redirect('http://www.baidu.com') return None def After(request,kargs): pass
七、动态路由的实现
#coding:utf-8 import string def Activator(request,controllerfile,controller,action,arg): namespace = __import__(controllerfile); model = getattr(namespace.Controllers, controller) func = getattr(model, action) result = func(request,arg); return result; def Execute(request,**arg): controller = string.capwords(arg['controller']) + 'Controller'; action = string.capwords(arg['action']); controllerfile = 'cmdbapp.Controllers.'+controller; return Activator(request,controllerfile,controller,action,arg);
八、开发注意
不能让用户看见错误
相关文章推荐
- python常用模块详解
- python爬虫
- Python 3 之 生成器详解
- python for循环语句怎么写
- Numpy——ndarray对象(2):数组存取和多维数组
- python小程序之一
- [Leetcode]214. Shortest Palindrome@python
- 《笨办法学Python》 第45课手记
- 使用Python Requests上传表单数据和文件
- python爬取百度搜索动态网页
- python闭包学习笔记四
- python闭包学习笔记三
- python闭包学习笔记二
- python闭包学习笔记一
- Python 3 之 lambda匿名函数详解
- python装饰器的学习笔记一
- 七牛---Python_SDK_Demos
- python装饰器的学习笔记二
- python装饰器的学习笔记三
- python logging 替代print 输出内容到控制台和重定向到文件