python 20 day form、model多对多操作、sql、中间件

跨站请求伪造:

一、简介

django为用户实现防止跨站请求伪造的功能,通过中间件 django.middleware.csrf.CsrfViewMiddleware 来完成。而对于django中设置防跨站请求伪造功能有分为全局和局部。

全局:

  中间件 django.middleware.csrf.CsrfViewMiddleware

局部:

  • @csrf_protect,为当前函数强制设置防跨站请求伪造功能,即便settings中没有设置全局中间件。
  • @csrf_exempt,取消当前函数防跨站请求伪造功能,即便settings中设置了全局中间件。

注:from django.views.decorators.csrf import csrf_exempt,csrf_protect

二、应用

1、普通表单

veiw中设置返回值:
  return render_to_response('Account/Login.html',data,context_instance=RequestContext(request))  
     或者
     return render(request, 'xxx.html', data)
  
html中设置Token:
  {% csrf_token %}

2、Ajax

对于传统的form,可以通过表单的方式将token再次发送到服务端,而对于ajax的话,使用如下方式。

view.py

from django.template.context import RequestContext
# Create your views here.
  
  
def test(request):
  
    if request.method == 'POST':
        print request.POST
        return HttpResponse('ok')
    return  render_to_response('app01/test.html',context_instance=RequestContext(request))

Text.html

 1 <!DOCTYPE html>
 2 <html>
 3 <head lang="en">
 4     <meta charset="UTF-8">
 5     <title></title>
 6 </head>
 7 <body>
 8     {% csrf_token %}
 9   
10     <input type="button" onclick="Do();"  value="Do it"/>
11   
12     <script src="/static/plugin/jquery/jquery-1.8.0.js"></script>
13     <script src="/static/plugin/jquery/jquery.cookie.js"></script>
14     <script type="text/javascript">
15         var csrftoken = $.cookie('csrftoken');
16   
17         function csrfSafeMethod(method) {
18             // these HTTP methods do not require CSRF protection
19             return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
20         }
21         $.ajaxSetup({
22             beforeSend: function(xhr, settings) {
23                 if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
24                     xhr.setRequestHeader("X-CSRFToken", csrftoken);
25                 }
26             }
27         });
28         function Do(){
29   
30             $.ajax({
31                 url:"/app01/test/",
32                 data:{id:1},
33                 type:'POST',
34                 success:function(data){
35                     console.log(data);
36                 }
37             });
38   
39         }
40     </script>
41 </body>
42 </html>
Text.html

Model

程序涉及到数据库的相关操作:

  • 创建数据库,设计表结构和字段
  • 使用 MySQLdb 来连接数据库,并编写数据访问层代码
  • 业务逻辑层去调用数据访问层执行数据库操作
 1 import MySQLdb
 2  
 3 def GetList(sql):
 4     db = MySQLdb.connect(user='root', db='wupeiqidb', passwd='1234', host='localhost')
 5     cursor = db.cursor()
 6     cursor.execute(sql)
 7     data = cursor.fetchall()
 8     db.close()
 9     return data
10  
11 def GetSingle(sql):
12     db = MySQLdb.connect(user='root', db='wupeiqidb', passwd='1234', host='localhost')
13     cursor = db.cursor()
14     cursor.execute(sql)
15     data = cursor.fetchone()
16     db.close()
17     return data
View Code

django使用一种新的方式,即关系对象映射(Object Relational Mapping ORM)

PHP:activerecord

  Java:Hibernate 

    C#:Entity Framework

django中遵循 Code Frist 的原则,即:根据代码中定义的类来自动生成数据库表。

创建表

基本结构

from django.db import models
   
class userinfo(models.Model):
    name = models.CharField(max_length=30)
    email = models.EmailField()
    memo = models.TextField()
 1 1、models.AutoField  自增列 = int(11)
 2   如果没有的话,默认会生成一个名称为 id 的列,如果要显示的自定义一个自增列,必须将给列设置为主键 primary_key=True。
 3 2、models.CharField  字符串字段
 4   必须 max_length 参数
 5 3、models.BooleanField  布尔类型=tinyint(1)
 6   不能为空,Blank=True
 7 4、models.ComaSeparatedIntegerField  用逗号分割的数字=varchar
 8   继承CharField,所以必须 max_lenght 参数
 9 5、models.DateField  日期类型 date
10   对于参数,auto_now = True 则每次更新都会更新这个时间;auto_now_add 则只是第一次创建添加,之后的更新不再改变。
11 6、models.DateTimeField  日期类型 datetime
12   同DateField的参数
13 7、models.Decimal  十进制小数类型 = decimal
14   必须指定整数位max_digits和小数位decimal_places
15 8、models.EmailField  字符串类型(正则表达式邮箱) =varchar
16   对字符串进行正则表达式
17 9、models.FloatField  浮点类型 = double
18 10、models.IntegerField  整形
19 11、models.BigIntegerField  长整形
20   integer_field_ranges = {
21     'SmallIntegerField': (-32768, 32767),
22     'IntegerField': (-2147483648, 2147483647),
23     'BigIntegerField': (-9223372036854775808, 9223372036854775807),
24     'PositiveSmallIntegerField': (0, 32767),
25     'PositiveIntegerField': (0, 2147483647),
26   }
27 12、models.IPAddressField  字符串类型(ip4正则表达式)
28 13、models.GenericIPAddressField  字符串类型(ip4和ip6是可选的)
29   参数protocol可以是:both、ipv4、ipv6
30   验证时,会根据设置报错
31 14、models.NullBooleanField  允许为空的布尔类型
32 15、models.PositiveIntegerFiel  正Integer
33 16、models.PositiveSmallIntegerField  正smallInteger
34 17、models.SlugField  减号、下划线、字母、数字
35 18、models.SmallIntegerField  数字
36   数据库中的字段有:tinyint、smallint、int、bigint
37 19、models.TextField  字符串=longtext
38 20、models.TimeField  时间 HH:MM[:ss[.uuuuuu]]
39 21、models.URLField  字符串,地址正则表达式
40 22、models.BinaryField  二进制
41 23、models.ImageField   图片
42 24、models.FilePathField 文件
更多字段
 1 1、null=True
 2   数据库中字段是否可以为空
 3 2、blank=True
 4   django的 Admin 中添加数据时是否可允许空值
 5 3、primary_key = False
 6   主键,对AutoField设置主键后,就会代替原来的自增 id 列
 7 4、auto_now 和 auto_now_add
 8   auto_now   自动创建---无论添加或修改,都是当前操作的时间
 9   auto_now_add  自动创建---永远是创建时的时间
10 5、choices
11 GENDER_CHOICE = (
12         (u'M', u'Male'),
13         (u'F', u'Female'),
14     )
15 gender = models.CharField(max_length=2,choices = GENDER_CHOICE)
16 6、max_length
17 7、default  默认值
18 8、verbose_name  Admin中字段的显示名称
19 9、name|db_column  数据库中的字段名称
20 10、unique=True  不允许重复
21 11、db_index = True  数据库索引
22 12、editable=True  在Admin里是否可编辑
23 13、error_messages=None  错误提示
24 14、auto_created=False  自动创建
25 15、help_text  在Admin中提示帮助信息
26 16、validators=[]
27 17、upload-to
更多参数

链表结构:

  • 一对多:models.ForeignKey(其他表)
  • 多对多:models.ManyToManyField(其他表)
  • 一对一:models.OneToOneField(其他表)

应用场景:

  • 一对多:当一张表中创建一行数据时,有一个单选的下拉框(可以被重复选择)
    例如:创建用户信息时候,需要选择一个用户类型【普通用户】【金牌用户】【铂金用户】等。
  • 多对多:在某表中创建一行数据是,有一个可以多选的下拉框
    例如:创建用户信息,需要为用户指定多个爱好
  • 一对一:在某表中创建一行数据时,有一个单选的下拉框(下拉框中的内容被用过一次就消失了
    例如:原有含10列数据的一张表保存相关信息,经过一段时间之后,10列无法满足需求,需要为原来的表再添加5列数据

 

 

 

 

 

二、操作表

1、基本操作表

 1 #
 2     #
 3     # models.Tb1.objects.create(c1='xx', c2='oo')  增加一条数据,可以接受字典类型数据 **kwargs
 4 
 5     # obj = models.Tb1(c1='xx', c2='oo')
 6     # obj.save()
 7 
 8     #
 9     #
10     # models.Tb1.objects.get(id=123)         # 获取单条数据,不存在则报错(不建议)
11     # models.Tb1.objects.all()               # 获取全部
12     # models.Tb1.objects.filter(name='seven') # 获取指定条件的数据
13 
14     #
15     #
16     # models.Tb1.objects.filter(name='seven').delete() # 删除指定条件的数据
17 
18     #
19     # models.Tb1.objects.filter(name='seven').update(gender='0')  # 将指定条件的数据更新,均支持 **kwargs
20     # obj = models.Tb1.objects.get(id=1)
21     # obj.c1 = '111'
22     # obj.save()                                                 # 修改单条数据
基本操作

2、进阶操作(了不起的双下划线)

利用双下划线将字段和对应的操作连接起来

 1 # 获取个数
 2     #
 3     # models.Tb1.objects.filter(name='seven').count()
 4 
 5     # 大于,小于
 6     #
 7     # models.Tb1.objects.filter(id__gt=1)              # 获取id大于1的值
 8     # models.Tb1.objects.filter(id__lt=10)             # 获取id小于10的值
 9     # models.Tb1.objects.filter(id__lt=10, id__gt=1)   # 获取id大于1 且 小于10的值
10 
11     # in
12     #
13     # models.Tb1.objects.filter(id__in=[11, 22, 33])   # 获取id等于11、22、33的数据
14     # models.Tb1.objects.exclude(id__in=[11, 22, 33])  # not in
15 
16     # contains
17     #
18     # models.Tb1.objects.filter(name__contains="ven")
19     # models.Tb1.objects.filter(name__icontains="ven") # icontains大小写不敏感
20     # models.Tb1.objects.exclude(name__icontains="ven")
21 
22     # range
23     #
24     # models.Tb1.objects.filter(id__range=[1, 2])   # 范围bettwen and
25 
26     # 其他类似
27     #
28     # startswith,istartswith, endswith, iendswith,
29 
30     # order by
31     #
32     # models.Tb1.objects.filter(name='seven').order_by('id')    # asc
33     # models.Tb1.objects.filter(name='seven').order_by('-id')   # desc
34 
35     # limit 、offset
36     #
37     # models.Tb1.objects.all()[10:20]
38 
39     # group by
40     from django.db.models import Count, Min, Max, Sum
41     # models.Tb1.objects.filter(c1=1).values('id').annotate(c=Count('num'))
42     # SELECT "app01_tb1"."id", COUNT("app01_tb1"."num") AS "c" FROM "app01_tb1" WHERE "app01_tb1"."c1" = 1 GROUP BY "app01_tb1"."id"
View Code

3、连表操作(了不起的双下划线)

利用双下划线和 _set 将表之间的操作连接起来

 1 class UserProfile(models.Model):
 2     user_info = models.OneToOneField('UserInfo')
 3     username = models.CharField(max_length=64)
 4     password = models.CharField(max_length=64)
 5 
 6     def __unicode__(self):
 7         return self.username
 8 
 9 
10 class UserInfo(models.Model):
11     user_type_choice = (
12         (0, u'普通用户'),
13         (1, u'高级用户'),
14     )
15     user_type = models.IntegerField(choices=user_type_choice)
16     name = models.CharField(max_length=32)
17     email = models.CharField(max_length=32)
18     address = models.CharField(max_length=128)
19 
20     def __unicode__(self):
21         return self.name
22 
23 
24 class UserGroup(models.Model):
25 
26     caption = models.CharField(max_length=64)
27 
28     user_info = models.ManyToManyField('UserInfo')
29 
30     def __unicode__(self):
31         return self.caption
32 
33 
34 class Host(models.Model):
35     hostname = models.CharField(max_length=64)
36     ip = models.GenericIPAddressField()
37     user_group = models.ForeignKey('UserGroup')
38 
39     def __unicode__(self):
40         return self.hostname
表结构实例
1 user_info_obj = models.UserInfo.objects.filter(id=1).first()
2 print user_info_obj.user_type
3 print user_info_obj.get_user_type_display()
4 print user_info_obj.userprofile.password
5  
6 user_info_obj = models.UserInfo.objects.filter(id=1).values('email', 'userprofile__username').first()
7 print user_info_obj.keys()
8 print user_info_obj.values()
一对一操作
1 类似一对一
2 1、搜索条件使用 __ 连接
3 2、获取值时使用 .    连接
一对多的
 1 user_info_obj = models.UserInfo.objects.get(name=u'武沛齐')
 2 user_info_objs = models.UserInfo.objects.all()
 3  
 4 group_obj = models.UserGroup.objects.get(caption='CEO')
 5 group_objs = models.UserGroup.objects.all()
 6  
 7 # 添加数据
 8 #group_obj.user_info.add(user_info_obj)
 9 #group_obj.user_info.add(*user_info_objs)
10  
11 # 删除数据
12 #group_obj.user_info.remove(user_info_obj)
13 #group_obj.user_info.remove(*user_info_objs)
14  
15 # 添加数据
16 #user_info_obj.usergroup_set.add(group_obj)
17 #user_info_obj.usergroup_set.add(*group_objs)
18  
19 # 删除数据
20 #user_info_obj.usergroup_set.remove(group_obj)
21 #user_info_obj.usergroup_set.remove(*group_objs)
22  
23 # 获取数据
24 #print group_obj.user_info.all()
25 #print group_obj.user_info.all().filter(id=1)
26  
27 # 获取数据
28 #print user_info_obj.usergroup_set.all()
29 #print user_info_obj.usergroup_set.all().filter(caption='CEO')
30 #print user_info_obj.usergroup_set.all().filter(caption='DBA')
多对多操作
 1 # F 使用查询条件的值
 2     #
 3     # from django.db.models import F
 4     # models.Tb1.objects.update(num=F('num')+1)
 5 
 6     # Q 构建搜索条件
 7     from django.db.models import Q
 8     # con = Q()
 9     #
10     # q1 = Q()
11     # q1.connector = 'OR'
12     # q1.children.append(('id', 1))
13     # q1.children.append(('id', 10))
14     # q1.children.append(('id', 9))
15     #
16     # q2 = Q()
17     # q2.connector = 'OR'
18     # q2.children.append(('c1', 1))
19     # q2.children.append(('c1', 10))
20     # q2.children.append(('c1', 9))
21     #
22     # con.add(q1, 'AND')
23     # con.add(q2, 'AND')
24     #
25     # models.Tb1.objects.filter(con)
26 
27     #
28     # from django.db import connection
29     # cursor = connection.cursor()
30     # cursor.execute("""SELECT * from tb where name = %s""", ['Lennon'])
31     # row = cursor.fetchone()
其他操作

注意:xx_set中的【_set】是多对多中的固定搭配

扩展:

a、自定义上传

1 def upload_file(request):
2     if request.method == "POST":
3         obj = request.FILES.get('fafafa')
4         f = open(obj.name, 'wb')
5         for chunk in obj.chunks():
6             f.write(chunk)
7         f.close()
8     return render(request, 'file.html')
自定义上传

b、form上传文件实例

1 class FileForm(forms.Form):
2     ExcelFile = forms.FileField()
form
1 from django.db import models
2 
3 class UploadFile(models.Model):
4     userid = models.CharField(max_length = 30)
5     file = models.FileField(upload_to = './upload/')
6     date = models.DateTimeField(auto_now_add=True)
model
1 def UploadFile(request):
2     uf = AssetForm.FileForm(request.POST,request.FILES)
3     if uf.is_valid():
4             upload = models.UploadFile()
5             upload.userid = 1
6             upload.file = uf.cleaned_data['ExcelFile']
7             upload.save()
8             
9             print upload.file
View Code

 

posted @ 2016-09-23 17:05  梁怀军  阅读(380)  评论(0编辑  收藏  举报