首页 > 代码库 > 2016年9月3日 文成小盆友python-num18 - django进阶一
2016年9月3日 文成小盆友python-num18 - django进阶一
一。深入django的路由系统
下面为django的请求生命周期
下面来看下整个生命周期中的路由系统:
在Django的urls中我们可以根据一个URL对应一个函数名来定义路由规则如下:
"""mysite_django URL ConfigurationThe `urlpatterns` list routes URLs to views. For more information please see: https://docs.djangoproject.com/en/1.10/topics/http/urls/Examples:Function views 1. Add an import: from my_app import views 2. Add a URL to urlpatterns: url(r‘^$‘, views.home, name=‘home‘)Class-based views 1. Add an import: from other_app.views import Home 2. Add a URL to urlpatterns: url(r‘^$‘, Home.as_view(), name=‘home‘)Including another URLconf 1. Import the include() function: from django.conf.urls import url, include 2. Add a URL to urlpatterns: url(r‘^blog/‘, include(‘blog.urls‘))"""from django.conf.urls import urlfrom django.contrib import adminfrom cmdb import viewsurlpatterns = [ url(r‘^admin/‘, admin.site.urls), url(r‘^index/‘, views.index), url(r‘^zhuce/‘, views.zhuce), url(r‘^houtai/‘, views.houtai), url(r‘^add/‘, views.add), url(r‘^err/‘, views.err), url(r‘^zichan/(\d+)/‘, views.zichan), url(r‘^chakan/(\d+)/‘, views.chakan),]
上面一个URL对应一个函数!我们可以在整个的url最下面里设置一个默认的URL,当用户访问我们的网站的时候没有指定详细的URL的时候我们默认让他们跳转到一个URL。
urlpatterns = [ url(r‘^admin/‘, admin.site.urls), url(r‘^index/‘, views.index), url(r‘^zhuce/‘, views.zhuce), url(r‘^houtai/‘, views.houtai), url(r‘^add/‘, views.add), url(r‘^err/‘, views.err), url(r‘^zichan/(\d+)/‘, views.zichan), url(r‘^chakan/(\d+)/‘, views.chakan), url(r‘^$‘, views.index) ##正则匹配]
动态URL
动态URL传参,的最多使用地方如下:
如上我梦可以看到一些网站的分页功能,如果不是动态的那么当分页很多时我们就得写对应数量的url,但是这里时支持正则表达式的。我们可以这样写(其实上面例子中已经写出了):
url(r‘^zichan/(\d+)/‘, views.zichan), url(r‘^chakan/(\d+)/‘, views.chakan),
对应的函数如下:这样我们就实现了一个url和函数的对应(以下函数着重看参数即可):
def chakan(request,nid): current_detail_dict = models.HostsInfo.objects.filter(id=nid) return render(request, ‘chakan.html‘, {‘current_detail_dict‘: current_detail_dict})def zichan(request,page): USER_LIST = [] # for item in range(94): # temp = {"id": item, ‘username‘: ‘alex‘ + str(item), ‘email‘: ‘email‘ + str(item)} # USER_LIST.append(temp) data_list = models.HostsInfo.objects.all() for item in data_list: temp = {"id": item.id, ‘zhujiming‘: item.zhujiming, ‘ip‘: item.ip} USER_LIST.append(temp) print("sdfsdfsd") # return HttpResponse(‘ok‘) print(page) # 1,0-9 # 2,10-19 # 3,20-29 page = int(page) start = (page - 1) * 10 end = page * 10 user_list = USER_LIST[start:end] if page ==1: page_shang=1 else: page_shang=page-1 data = {"user_list" : user_list,"page_xia":page+1,"page_shang":page_shang,"page":page,} # return HttpResponse(‘OK‘) # print(data[1]) # print(data[0]) return render(request, ‘zichan.html‘, {‘data‘: data})
他这里会做两步操作:
1、获取user_list后面的这个值
2、运行views.user_list这个函数,并把获取的值自动传给views.user_list作为参数他的参数
动态URL传多个参数
可以传多个参数它是以/来分割的。
url(r‘^user_list/(\d+)/(\d+)$‘, views.user_list),
views.user_list
def user_list(request,chose_id,chose_id2): return HttpResponse(chose_id+chose_id2)
他的顺序是:正序的,你先给他传那个值,第一个参数就是那个
下面来看一个无序的:
动态URL传参数以Key:value的形式通过正则表达式的分组来做!
url(r‘^user_list/(?P<v1>\d+)/(?P<V2>\d+)$‘, views.user_list),
这里?p<v1>这里的v1就是key,vlaue就是传进去的值,
def user_list(request,v2,v1): print v2 , v1 return HttpResponse(v1+v2)
这样我们就不必按照顺序去取了,可以通过key,value的方式来取传进来的值!!
模版语言
1、模版的执行
模版的创建过程,对于模版,其实就是读取模版(其中嵌套着模版标签),然后将 Model 中获取的数据插入到模版中,最后将信息返回给用户。
def current_datetime(request): now = datetime.datetime.now() html = "<html><body>It is now %s.</body></html>" % now return HttpResponse(html)
from django import templatet = template.Template(‘My name is {{ name }}.‘)c = template.Context({‘name‘: ‘Adrian‘})print t.render(c)
import datetimefrom django import templateimport DjangoDemo.settings now = datetime.datetime.now()fp = open(settings.BASE_DIR+‘/templates/Home/Index.html‘)t = template.Template(fp.read())fp.close()html = t.render(template.Context({‘current_date‘: now}))return HttpResponse(html
from django.template.loader import get_templatefrom django.template import Contextfrom django.http import HttpResponseimport datetime def current_datetime(request): now = datetime.datetime.now() t = get_template(‘current_datetime.html‘) html = t.render(Context({‘current_date‘: now})) return HttpResponse(html)
return render_to_response(‘Account/Login.html‘,data,context_instance=RequestContext(request))
2、模版语言
模板中也有自己的语言,该语言可以实现数据展示
- {{ item }}
- {% for item in item_list %} <a>{{ item }}</a> {% endfor %}
forloop.counter
forloop.first
forloop.last - {% if ordered_warranty %} {% else %} {% endif %}
- 母板:{% block title %}{% endblock %}
子板:{% extends "base.html" %}
{% block title %}{% endblock %} - 帮助方法:
{{ item.event_start|date:"Y-m-d H:i:s"}}
{{ bio|truncatewords:"30" }}
{{ my_list|first|upper }}
{{ name|lower }}
3、自定义simple_tag
a、在app中创建templatetags模块
b、创建任意 .py 文件,如:xx.py
#!/usr/bin/env python#coding:utf-8from django import templatefrom django.utils.safestring import mark_safefrom django.template.base import resolve_variable, Node, TemplateSyntaxError register = template.Library() @register.simple_tagdef my_simple_time(v1,v2,v3): return v1 + v2 + v3 @register.simple_tagdef my_input(id,arg): result = "<input type=‘text‘ id=‘%s‘ class=‘%s‘ />" %(id,arg,)
c、在使用自定义simple_tag的html文件中导入之前创建的 xx.py 文件名
{% load xx %}
d、使用simple_tag
{% my_simple_time 1 2 3%}{% my_input ‘id_username‘ ‘hide‘%}
e、在settings中配置当前app,不然django无法找到自定义的simple_tag
INSTALLED_APPS = ( ‘django.contrib.admin‘, ‘django.contrib.auth‘, ‘django.contrib.contenttypes‘, ‘django.contrib.sessions‘, ‘django.contrib.messages‘, ‘django.contrib.staticfiles‘, ‘app01‘,)
三.Ajax
1、单条数据提交
<script src=http://www.mamicode.com/"/static/js/commons.js"></script> <script> $(function(){ $.valid(‘#form1‘); }); function SubmitForm() { $.ajax({ url: ‘/index/‘, type: ‘POST‘, data: {‘username‘:$(‘#username‘).val(),‘password‘:$(‘#password‘).val()}, #获取表单的数据 success: function (data) { if (data =http://www.mamicode.com/= ‘1‘){ #这里的data是后端的返回值 location.href = "/zichan/1" }else { alert(‘用户名or密码错误‘) } } }) } </script>
对应的后端验证如下:
def index(request): ‘‘‘ index 界面请求处理,主要做用户数据的验证,验证成功后做后端的跳转。 :param request: 传递的参数。 :return:返回给前端 ‘‘‘ #return HttpResponse("<h1>zhaowencheng</h1>") if (request.method == ‘POST‘): u = request.POST.get(‘username‘,None) pa = request.POST.get(‘password‘,None) if int(len(u)) == 0 or int(len(pa)) == 0: pass else: data_list = models.UserInfo.objects.all() for i in data_list: if u == i.username and pa == i.password: print("登录成功") #return redirect(‘/houtai/‘) return HttpResponse(‘1‘) else: return HttpResponse(‘0‘) # info = 2 return render(request,‘index.html‘)
2、关于后端的返回值
#不规范的示例def ajax_data(request): print request.POST return HttpResponse(‘OK‘)应该这么写:(下面的例子先用json来做,不过还有一个json response)import jsondef ajax_data(request): ret = {‘status‘:True,‘error‘:‘‘} try: print request.POST except Exception,e: ret[‘status‘] = False ret[‘error‘] = str(e) #在上面如果他出错我就把他ret[status] = False return HttpResponse(json.dumps(ret))
四:model
到目前为止,当我们的程序涉及到数据库相关操作时,我们一般都会这么搞:
- 创建数据库,设计表结构和字段
- 使用 MySQLdb 来连接数据库,并编写数据访问层代码
- 业务逻辑层去调用数据访问层执行数据库操作
import MySQLdb def GetList(sql): db = MySQLdb.connect(user=‘root‘, db=‘cheng‘, 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=‘cheng‘, passwd=‘1234‘, host=‘localhost‘) cursor = db.cursor() cursor.execute(sql) data = cursor.fetchone() db.close() return data
django为使用一种新的方式,即:关系对象映射(Object Relational Mapping,简称ORM)。
PHP:activerecord
Java:Hibernate
C#:Entity Framework
django中遵循 Code Frist 的原则,即:根据代码中定义的类来自动生成数据库表。
1、创建Model,之后可以根据Model来创建数据库表
from django.db import models class userinfo(models.Model): name = models.CharField(max_length=30) email = models.EmailField() memo = models.TextField()
更多的参考表字段:*****
1、models.AutoField 自增列 = int(11) 如果没有的话,默认会生成一个名称为 id 的列,如果要显示的自定义一个自增列,必须将给列设置为主键 primary_key=True。2、models.CharField 字符串字段 必须 max_length 参数3、models.BooleanField 布尔类型=tinyint(1) 不能为空,Blank=True4、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_places8、models.EmailField 字符串类型(正则表达式邮箱) =varchar 对字符串进行正则表达式9、models.FloatField 浮点类型 = double10、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 正Integer16、models.PositiveSmallIntegerField 正smallInteger17、models.SlugField 减号、下划线、字母、数字18、models.SmallIntegerField 数字 数据库中的字段有:tinyint、smallint、int、bigint19、models.TextField 字符串=longtext20、models.TimeField 时间 HH:MM[:ss[.uuuuuu]]21、models.URLField 字符串,地址正则表达式22、models.BinaryField 二进制23、models.ImageField 图片24、models.FilePathField 文件更多字段
更多的参考参数:
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、choicesGENDER_CHOICE = ( (u‘M‘, u‘Male‘), (u‘F‘, u‘Female‘), )gender = models.CharField(max_length=2,choices = GENDER_CHOICE)6、max_length7、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、连表关系:
- 一对多,models.ForeignKey(ColorDic)
- 一对一,models.OneToOneField(OneModel)
- 多对多,authors = models.ManyToManyField(Author)
3、数据库操作
- 增加:创建实例,并调用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(SQLBETWEEN查询)‘gt‘, ‘in‘, ‘isnull‘, ‘endswith‘, ‘contains‘, ‘lt‘, ‘startswith‘, ‘iendswith‘, ‘icontains‘,‘range‘, ‘istartswith‘ - 排序:order_by("name") =asc ;order_by("-name")=desc
- 返回第n-m条:第n条[0];前两条[0:2]
- 指定映射:values
- 数量:count()
- 聚合:from django.db.models import Min,Max,Sum objects.all().aggregate(Max(‘guest_id‘))
- 原始SQL
文件上传实例:
#Formclass FileForm(forms.Form): ExcelFile = forms.FileField()#modelfrom django.db import modelsclass UploadFile(models.Model): userid = models.CharField(max_length = 30) file = models.FileField(upload_to = ‘./upload/‘) date = models.DateTimeField(auto_now_add=True)#viewsdef UploadFile(request): uf = AssetForm.FileForm(request.POST,request.FILES) if uf.is_valid(): upload = models.UploadFile() upload.userid = 1 upload.file = uf.cleaned_data[‘ExcelFile‘] upload.save() print upload.fileView
2016年9月3日 文成小盆友python-num18 - django进阶一