django中如何操作数据库

一.from的基本功能应用

1.1.保存用户输入

建立form对象时.把POST对象传进去.则可以用户输入验证错误返回页面时.保存用户以前的输入,提高用户体验.

 

1

2

3

def login(request):

    obj = LoginForm(request.POST)              #如果是第一次加载页面.则Post为空.也不会报错

    return render(request, 'account/login.html', {'obj': obj})

 

1.2.from验证错误信息原始对象格式

from验证错误时.通过obj.errors能拿到错误的信息.它有3种格式

obj.errors------------->原始的对象,一般是from请求时用.在静态的模板中应用.

 

1

2

3

4

5

6

7

8

9

<class 'django.forms.utils.ErrorDict'>

<ul class="errorlist">

  <li>

    username

    <ul class="errorlist">

        <li>This field is required.</li>

    </ul>

  </li>

</ul>

在模板中获取错误信息,不能通过括号,只能能过点

 

1

<span>{{ errors.username }}</span>

前台输出的是ul,不是纯文本.

 

1

<span class="html-tag"><ul <span class="html-attribute-name">class</span>="<span class="html-attribute-value">errorlist</span>"></span><span class="html-tag"><li></span>This field is required.<span class="html-tag"></li></span><span class="html-tag"></ul></span>

类为他是个django的错误列表,在后台页面获取方式使用[]

 

1

2

<class 'django.forms.utils.ErrorList'>

print errors['username'][0]   #输出为:This field is required.

输出纯文本,需要自定义simple-tag来处理

A.建立

D:\python\day19\cmdb\templatetags 包

B.新建tag的文件

 

1

2

3

4

5

6

7

8

9

10

11

12

13

#!/usr/bin/env python

#coding:utf-8

from django import template

from django.utils.safestring import mark_safe

from django.template.base import resolve_variable, Node, TemplateSyntaxError

register = template.Library()

 

@register.simple_tag

def msg_error(error_list):

    if error_list:

        return error_list[0]

 

    return ''

C.模板页面引用

 

1

2

3

{% load  login_tag %}

 

<span>{%  msg_error errors.username  %}</span>   #使用tag标签来处理

 

1.3.from验证错误信息json格式

obj.errors.as_json------------>json对象.一般是ajxa请求时用.因为ajax请求时.不能返回对象.需要变成字符串.

错误类型如下:

 

1

2

3

4

5

6

{

"username":

[{"message": "This field is required.", "code": "required"}],

"password":

[{"message": "This field is required.", "code": "required"}]

}

 

 1.4.form表单生成select标签

from类中先定义

 

1

2

3

host_type = forms.IntegerField(

        widget=forms.Select()

)

因为是类的静态字段.上述的定义会存在取数据不会实时更新问题.所以可以在类的构造函数中.进行初始化.这样,每次加载页面.都可以去数据库中取取数据

 

1

2

3

4

def __init__(self, *args, **kwargs):

    super(LoginForm, self).__init__(*args, **kwargs)  #执行下父类的构造函数

    host_data = models.UserInfo.objects.all().values_list("id", "username")  #取数据

    self.fields['host_type'].widget.choices = host_data  #赋值

 

 

二.model操作进阶

2.1.关系对象映射(Object Relational Mapping,简称ORM)

model类代表数据库的表

model对象代表数据库表的一行记录

对象.value------------>每行里面具体的数据

 

 2.2.model常用的字段

 

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

1、models.AutoField  自增列 = int(11)

#如果没有的话,默认会生成一个名称为 id 的列,如果要显示的自定义一个自增列,必须将给列设置为主键 primary_key=True。

2、models.DateField  日期类型 date

参数:auto_now = True 则每次更新都会更新这个时间;

auto_now_add 则只是第一次创建添加,之后的更新不再改变   #测试后发现只在admin修改中用效

3、models.Decimal  十进制小数类型 = decimal

  必须指定数位max_digits和小数位decimal_places

4、models.EmailField  字符串类型(正则表达式邮箱) =varchar   对字符串进行正则表达式

5、models.FloatField  浮点类型 = double10、models.IntegerField  整形

6、models.BigIntegerField  长整形

  integer_field_ranges = {

    'SmallIntegerField': (-32768, 32767),

    'IntegerField': (-2147483648, 2147483647),

    'BigIntegerField': (-9223372036854775808, 9223372036854775807),

    'PositiveSmallIntegerField': (0, 32767),

    'PositiveIntegerField': (0, 2147483647),

  }

7、models.GenericIPAddressField  字符串类型(ip4和ip6是可选的)

  参数protocol可以是:both、ipv4、ipv6

  验证时,会根据设置报错

8、models.ImageField   图片 upload参数,设置保存路径

9、models.FilePathField 文件

注:以上大部份参数,主要是admin后台页面使用.

 

 2.3.字段参数

 

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

1、<span style="color: #ff0000;">null=True</span>

  数据库中字段是否可以为空

2、blank=True

  django的 Admin 中添加数据时是否可允许空值

3、<span style="color: #ff0000;">primary_key</span> = False

  主键,对AutoField设置主键后,就会代替原来的自增 id 列

4、auto_now 和 auto_now_add

  auto_now 自动创建---无论添加或修改,都是当前操作的时间

  auto_now_add 自动创建---永远是创建时的时间

5、<span style="color: #ff0000;">choices</span>

GENDER_CHOICE = (

(u'M', u'Male'),

(u'F', u'Female'),

)

gender = models.CharField(max_length=2,choices = GENDER_CHOICE)

6、<span style="color: #ff0000;">max_length</span>           #char类型必段要写,不写会报错

7、<span style="color: #ff0000;">default</span>  默认值

8、verbose_name  Admin中字段的显示名称

9、name|db_column  数据库中的字段名称

10、<span style="color: #ff0000;">unique=True</span>  不允许重复

11、<span style="color: #ff0000;">db_index = True</span>  数据库索引

12、editable=True  在Admin里是否可编辑

13、error_messages=None  错误提示

14、help_text  在Admin中提示帮助信息

15、<span style="color: #ff0000;">validators=[]   #使用验证函数,与forms中类似</span>

16、upload-to  #设置上传到那个路径

 

 2.4.各种models的字段和form的字段区别

models的字段作用:为了后台/admin,添加数据时.进行验证.因为admin后台录入数据,没有经过类似前以的from表达验证.防止出现脏数据.

from的字段:前台form输入时.进行验证.

所以才有了2套规则.规则非常相似!!

 

 2.5.form文件上传实例

 

 

1

2

3

4

<form method="post" action="/cmdb/login/" enctype="multipart/form-data">

    <input type="file" name="f1">

    <input type="submit" value="提交">

</form>

view处理函数

 

1

2

3

4

5

6

7

inp_files = request.FILES         #获取 所有的文件对象

file_obj1 = inp_files.get("f1")   #获取上传文件的内存对象

f = open(file_obj1.name, "wb")    #打开写入的文件

 

for line in file_obj1.chunks():   #分片读取文件内容,写入到服务器

    f.write(line)

f.close()

 

二.数据库Model操作建表

2.1.数据库建表一对多(外键)

一对多.指表的一个字段的值,对应另外个表的字段的多个值.

 

1

2

3

4

5

6

class Bussines(models.Model):

    dep_name = models.CharField(max_length=64)

 

class Host(models.Model):

    host_name = models.CharField(max_length=32)

    dep = models.ForeignKey('Bussines')    #外键

 

2.2.数据库建表多对多

 

 

1

2

3

4

5

6

7

8

class User_Group(models.Model):

    group_name = models.CharField(max_length=32)

 

class User(models.Model):

    name = models.CharField(max_length=32)

    password = models.CharField(max_length=32)

    email = models.CharField(max_length=32)

    user_group = models.ManyToManyField("User_Group")     #会创建第3张表.进行多对多

django中如何操作数据库

 

 2.3.建表之一对一

A表中的数据只能在B表中出现一次

 

1

2

3

4

5

6

7

8

class AAdmin(models.Model):

    name = models.CharField(max_length=32)

    password = models.CharField(max_length=32)

 

class User2(models.Model):

    user_name = models.CharField(max_length=32)

    email = models.CharField(max_length=32)

    user_info = models.OneToOneField("AAdmin")        #一对一的关系

 

三.数据库单表的基本操作

3.1.增加数据:

 

 

1

2

3

4

    法一: models.Tb1.objects.create(c1='xx', c2='oo')  增加一条数据,可以接受字典类型数据 **kwargs

    法二: obj = models.Tb1(c1='xx', c2='oo')

          obj.save()

    法三:models.Tb1.objects.create(**dic) 接受个字典

 

 

3.2.查数据:

 

 

1

2

3

4

5

    法一:models.Tb1.objects.get(id=123) # 获取单条数据,不存在则报错(不推荐使用)

    法二:models.Tb1.objects.all() # 获取整张表的数据

    法三:models.Tb1.objects.filter(name='seven', gender="0") # 获取指定条件的数据

    法四:models.Tb1.objects.filter(**dic)  #也可以传字典来判断

    法五:models.Tb1.objects.all().first()  #取第一条数据

 

3.3.查询数据得到的结果类型

 

 

1

2

 <class 'django.db.models.query.QuerySet'>          #是django的自定义的查询的结果集

[<User: User object>]                                #all方法返回一个结果集列表

查询指定的列法一:

 

1

2

3

user_model_obj = models.User.objects.all().values("name", 'email')

print type(user_model_obj)

print user_model_obj

返回的结果是字典列表

 

1

2

<class 'django.db.models.query.QuerySet'>

[{'name': u'alex', 'email': u'[email protected]'}]

查询指定的列法二:

 

1

user_model_obj = models.User.objects.all().values_list("name", 'email')

返加的结果是元组列表

 

1

[(u'alex', u'[email protected]')]

 

3.4.删除数据

 

 

1

2

   法一:models.Tb1.objects.filter(name='seven').delete() # 删除指定条件的数据

   法二:models.Tb1.objects.filter(**did).delete()  #也可以传字典进去

 

3.5.修改数据

 

 

1

2

3

4

    法一: models.Tb1.objects.filter(name='seven').update(gender='0')  #将指定条件的数据更新,均支持 **kwargs

    法二:obj = models.Tb1.objects.get(id=1)

         obj.c1 = '111'

         obj.save()                                                 #修改单条数据

 

 四.数据库单表进阶操作

4.1.获取数据个数

 

 

1

user_count = models.User.objects.all().filter(name="alex").count()

 

4.2.查询条件中使用大于,小于,等于

 

 

1

2

3

4

5

user_model_obj = models.User.objects.all().filter(id__gt=2)   #大于

user_model_obj = models.User.objects.all().filter(id__lt=2)   #小于

user_model_obj = models.User.objects.all().filter(id=2)       #等于

 

user_model_obj = models.User.objects.all().filter(id__gt=1, id_lt=10)   #大于1, 小于10

结果

 

1

2

3

[<User: 3>, <User: 4>]

[<User: 1>]

[<User: 2>]

 

4.3.查询条件使用in 和 not in

 

 

1

2

user_model_obj = models.User.objects.all().filter(id__in=[1, 2])

user_model_obj = models.User.objects.all().exclude(id__in=[1, 2])

结果

 

1

2

[<User: 1>, <User: 2>]

[<User: 3>, <User: 4>]

 

4.4.查询条件使用like(包含每些字符)

 

 

1

2

3

    models.Tb1.objects.filter(name__contains="ven")

    models.Tb1.objects.filter(name__icontains="ven") # icontains大小写不敏感

    models.Tb1.objects.exclude(name__icontains="ven")  #不包含ven

 

4.5.查询条件使用bettwen and

 

 

1

user_model_obj = models.User.objects.filter(id__range=[1, 3])

获取结果

 

1

[<User: 1>, <User: 2>, <User: 3>]

 

4.6.查询条件以什么开头

 

 

1

startswith,istartswith, endswith, iendswith,

 

4.7.升序,降序排列

 

 

1

2

user_model_obj = models.User.objects.filter(id__range=[1, 3]).order_by('id')

user_model_obj = models.User.objects.filter(id__range=[1, 3]).order_by('-id')

返回结果

 

1

2

[<User: 1>, <User: 2>, <User: 3>]

[<User: 3>, <User: 2>, <User: 1>]

 

4.8. 从什么开始取几个l

 

 

1

user_model_obj = models.User.objects.all()[1:4]  #从第一条开始取,取到第四条,不包括第1条

 

 

1

[<User: 2>, <User: 3>, <User: 4>]

 

4.9.分组groupby.聚合函数使用

 

 

1

2

3

4

5

6

from django.db.models import Count, Min, Max, Sum

 

models.Tb1.objects.filter(c1=1).values('id').annotate(c=Count('num'))

#根椐ID进行分组,然后对num进行求和,得到一个新列c

 

SELECT "app01_tb1"."id", COUNT("app01_tb1"."num") AS "c" FROM "app01_tb1" WHERE "app01_tb1"."c1" = 1 GROUP BY "app01_tb1"."id"

 

五.表一对多的操作

5.1. 2张表外键约束,添加数据操作

法一.外键列的值使用对象(稍显复杂)

 

1

2

3

4

5

6

7

8

group_obj = models.User_Group.objects.get(id=all_data['user_group_id'])

 

models.User.objects.create(

     name=all_data['username'],

     password=all_data['password'],

     email=all_data['email'],

     user_group = group_obj

)

 

法二.直接使用外键的表字段

POST的传递过来的数据.直接用

 

1

user_group_id = all_data['user_group_id']   #此方法更简便

 

外键建表时models中的定义

 

1

user_group = models.ForeignKey("User_Group")   #<span style="color: #ff0000;">user_group 代表的是一个对象</span>

 

5.2.联表操作获取数据

views层,取得数据

 

1

2

user_list = models.User.objects.all()

return render(request, 'account/login.html', {'obj': obj, "user_list": user_list})

模板中渲染

 

1

2

3

4

5

6

7

{% for item in user_list %}

<tr>

    <td>{{ item.id }}</td>

    <td>{{ item.name }}</td>

    <td>{{ item.user_group.group_name }}</td>      #外键在Model层定义时代表的是一个对象.可以直接调用其字段

</tr>

{% endfor %}

 

view层.通过外键对应的值获取数据(使用了不起的双划线来处理___),跨表时

 

1

2

val =request.GET['user_group']

user_list = models.User.objects.filter(user_group<span style="color: #ff0000;">__group_name</span>= val )  #外键名__关联表的字段名

 

总结:

1.model中定义的外键代指一个对象

2.添加数据时.可以使用外键的字段如(user_group_id)

3.查询数据时.可以使用 . 来获取

4.view中跨表查数据,过滤使用__来查

5.多张表中,可以连续使用__来实现 (user_group__group_name__aa)

6.以上规则,同样适用一对一的表