Django测试开发-10-models
1.Django使用MySQL配置
pip3 install pymysql
pip3 install mysqlclient
使用MySQL需要在settings.py中配置
DATABASES = { 'default': { 'ENGINE':'django.db.backends.mysql',#选择mysql数据库 'NAME':'my_app',#数据库的名字 'USER':'root',#mysql数据库的用户名 'PASSWORD':'123456',#mysql数据库的密码 'HOST':'127.0.0.1',#mysql数据库的主机名 'POST':3306,#mysql数据库的端口号(这个可写可不写) } }
2.Django与MySQL交互
(1)创建数据库的表类,类名代表了数据库表名,且继承了models.Model,类里面的字段代表数据表中的字段
(2)对数据库表进行同步操作,python manage.py makemigrations,python manage.py migrate
(3)使用数据库表类,进行数据库的增删改查操作。
3.字段类型详解
#django的models里面字段类型除了上面的常用的 models.CharField和models.IntegerField,还有更多的类型 # # 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 例子:2020-04-02 # 对于参数,auto_now =True则每次更新都会更新这个时间;auto_now_add 则只是第一次创建添加,之后的更新不再改变。 # 6.models.DateTimeField 日期类型 datetime 例子:2020-04-02 15:44:09.151728 # 同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文件
对应的字段参数详解
#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'), # ) # gender = models.CharField(max_length=2,choices = GENDER_CHOICE) # 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
4.实际操作
4.1 创建Hero数据库表类:
from django.db import models # Create your models here. class Hero(models.Model): name = models.CharField('英雄名',max_length=50) propertys = models.CharField('英雄属性',max_length=50) is_male = models.BooleanField('是否男性',null=False) power = models.IntegerField('武力值',default=1) time_stamp = models.DateTimeField() # 时间 ,datetime类型
4.2 添加urls.py规则
url(r"hero",views.hero)
4.3 hero.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Hero页面</title> </head> <body> <h1>用户输入:</h1> <form action="/vote/hero/" method="post"> 英雄 名:<input type="text" name="name"/><br/> 英雄属性:<input type="text" name="propertys"/><br/> 是否男性:<input type="text" name="is_male"/><br/> 武力 值:<input type="text" name="power"/><br/> 当前时间:<input type="date" name="time_stamp"/><br/> <input type="submit" value="提交"/> </form> <h1>英雄展示:</h1> <table border="1"> <thead> <tr>英雄名</tr> <tr>英雄属性</tr> <tr>是否男性</tr> <tr>武力值</tr> <tr>保存时间</tr> </thead> <tbody> {% for item in data %} <tr> <td>{{ item.name }}</td> <td>{{ item.propertys }}</td> <td>{{ item.is_male }}</td> <td>{{ item.power }}</td> <td>{{ item.time_stamp }}</td> </tr> {% endfor %} </tbody> </table> </body> </html>
4.4 添加views.py 视图
def hero(request): if request.method == 'POST': name = request.POST.get('name') propertys = request.POST.get('propertys') is_male = request.POST.get('is_male') power = request.POST.get('power') time_stamp = request.POST.get('time_stamp') print(name,propertys,is_male,power,time_stamp,type(name)) hero = Hero(name=name,propertys=propertys,is_male=is_male,power=power,time_stamp=time_stamp) hero.save() data = Hero.objects.all() return render(request,'hero.html',{'data':data})
浏览器输入:http://127.0.0.1:8000/vote/hero/
4.5 查询实例
views.py
def select_data(request): ''' 查询数据 :param request: :return: ''' ctx = {} ctr = [] hero = Hero.objects.get(name="战狼") print(type(hero)) # <class 'vote.models.Hero'> all_hero = Hero.objects.all() for i in all_hero: print(i.name) order_by = Hero.objects.order_by("name") for i in order_by: print(i.name) ctr.append(i.name) ctx["name"] = ctr print("ctr="+str(ctr)) print("ctx="+str(ctx)) return render(request,"select_hero.html",ctx)
hero.html页面新增
<form action="/vote/select_data/" method="get"> <input type="submit" value="查询"/> </form>
select_hero.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>查询页面</title> </head> <body> <h1>{{ name }}</h1> {% for foo in name %} <p>{{ foo }}</p> {% endfor %} </body> </html>
页面展示为:
urls.py
url(r"^select_data",views.select_data)
浏览器访问:http://127.0.0.1:8000/vote/hero/
点击查询:
4.6 删除数据
def delete_hero(request,id): ''' 删除数据 :param request: :return: ''' Hero.objects.filter(id=id).delete() return HttpResponse("数据删除成功!")
4.7 修改数据
def update_hero(request,name): ''' 修改数据 :param request: :param name: :return: ''' # 1.根据属性查询到数据后,对属性进行修改,然后调用save方法保存 hero = Hero.objects.get(name=name) hero.power = 1111 hero.save() # 2.根据属性查询到数据后,直接调用update()方法 Hero.objects.filter(name=name).update(name=name+name) # 3.调用all方法的update方法 Hero.objects.all().update(is_male = False) return HttpResponse("修改成功!")
五、查询的各种方法
查询方法根据返回结果分类如下: #返回对象是对象列表的: all(), filter(), exclude(), order_by(), reverse(), values(), values_list(), distinct() #返回结果是对象: get(), first(), last() #返回结果是布尔值: exists() #返回数字: count() #返回对象列表即queryset序列,可以通过for循环进行获取每一个对象,然后使用对象调用对应的属性。也可以通过下标取某个对象,
然后调用对应的属性。使用切片操作也可以获取其中某几个对象。
5.1 all()函数:查询所有
def select_data1(request): ''' 查询数据 :param request: :return: ''' ctx = {} ctr = [] #查询所有 all_hero = Hero.objects.all() for i in all_hero: print(i.name) order_by = Hero.objects.order_by("name") for i in order_by: print(i.name) ctr.append(i.name) ctx["result1"] = ctr return render(request, "select_hero_one.html", ctx)
select_data_one.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>查询所欲数据页面</title> </head> <body> {% for foo in result1 %} <p>{{ foo }}</p> {% endfor %} </body> </html>
结果:
5.2 filter():根据条件过滤,可返回多个
def select_data4(request): ''' 查询数据 :param request: :return: ''' ctx = {} ctr = [] # 根据条件查询 result4 = Hero.objects.all().filter(name="战狼",is_male=True) print(result4) for i in result4: res = i.name print(i.name) print(res) ctr.append(res) ctx["result4"] = ctr return render(request, "select_hero_four.html", ctx)
5.3 values_list和values
values函数,可以由queryset序列调用values函数,返回值是一个字典
values_list函数,返回值是一个元组序列
values
def select_data2(request): ''' 查询数据 :param request: :return: ''' ctx = {} ctr = [] result2 = Hero.objects.all().values_list("name","is_male","is_male","time_stamp","propertys") result2 = Hero.objects.all().values("name","is_male","is_male","time_stamp","propertys") # print(result) for i in result2: print(i) ctr.append(i) ctx["result2"] = ctr return render(request, "select_hero_two.html", ctx)
values_list
def select_data2(request): ''' 查询数据 :param request: :return: ''' ctx = {} ctr = [] result2 = Hero.objects.all().values_list("name","is_male","is_male","time_stamp","propertys") #result2 = Hero.objects.all().values("name","is_male","is_male","time_stamp","propertys") # print(result) for i in result2: print(i) ctr.append(i) ctx["result2"] = ctr return render(request, "select_hero_two.html", ctx)
select_hero_two.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>查询values_list页面</title> </head> <body> {% for foo in result2 %} <p>{{ foo }}</p> {% endfor %} </body> </html>
结果:
values
values_list
5.4 exclude() 它包含了与所给筛选条件不匹配的对象 调用者:objects管理器 返回queryset
def select_data3(request): ''' 查询数据 :param request: :return: ''' ctx = {} ctr = []
#返回的是name不等于诺克萨斯的对象集合
result3 = Hero.objects.exclude(name="战狼")
print(result3) for i in result3: res = i.name print(i.name) print(res) ctr.append(res) ctx["result3"] = ctr return render(request, "select_hero_three.html", ctx)
select_hero_three.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>查询exclude页面</title> </head> <body> {% for foo in result3 %} <p>{{ foo }}</p> {% endfor %} </body> </html>
结果
5.5 order_by() 对查询结果排序 由queryset对象调用,返回值是queryset,默认升序,前面加个-是代表降序
升序
def select_data1(request): ''' 查询数据 :param request: :return: ''' ctx = {} ctr = [] all_hero = Hero.objects.all() for i in all_hero: print(i.name) order_by = Hero.objects.order_by("power") for i in order_by: print(i.name) ctr.append(i.name+"-"+str(i.power)) ctx["result1"] = ctr return render(request, "select_hero_one.html", ctx)
降序
def select_data1(request): ''' 查询数据 :param request: :return: ''' ctx = {} ctr = [] all_hero = Hero.objects.all() for i in all_hero: print(i.name) order_by = Hero.objects.order_by("-power") for i in order_by: print(i.name) ctr.append(i.name+"-"+str(i.power)) ctx["result1"] = ctr return render(request, "select_hero_one.html", ctx)
结果:
5.6 reverse() 对查询结果反向排序 由queryset对象调用,返回值是queryset
order_by = Hero.objects.order_by("-power").reverse()
结果为升序排列
5.7 distinct() 从返回结果中筛选重复纪录 由queryset对象调用,返回值是queryset
未筛选前
def select_data5(request): ''' 查询数据 :param request: :return: ''' ctx = {} ctr = [] result5 = Hero.objects.values("name","propertys") for i in result5: res = i ctr.append(res) ctx["result5"] = ctr return render(request,"select_hero_five.html",ctx)
结果:
筛选后
result5 = Hero.objects.values("name","propertys").distinct()
结果:
5.8 first()和last():返回第一条记录和返回最后一条记录 调用者:queryset 返回model对象
def select_data6(request): ''' 查询数据 :param request: :return: ''' ctx = {} ctr = [] result6 = Hero.objects.all().order_by("-power") print(result6) result6 = result6.first() print(result6) ctr.append(result6.name) ctx["result6"] = ctr return render(request,"select_hero_six.html",ctx)
输出:
<QuerySet [<Hero: Hero object (10)>, <Hero: Hero object (12)>, <Hero: Hero object (13)>, <Hero: Hero object (9)>, <Hero: Hero object (11)>]>
Hero object (10)
5.9 exists() 如果QuerySet包含数据,就返回True,否则返回False 由queryset对象调用 返回值布尔值
def select_data7(request): ''' 查询数据 :param request: :return: ''' ctx = {} ctr = [] result7 = Hero.objects.all().exists() print(result7) ctx["result7"] = result7 return render(request,"select_hero_seven.html",ctx)
5.10 count() 由queryset对象调用 返回int
def select_data8(request): ''' 查询数据 :param request: :return: ''' ctx = {} ctr = [] result8 = Hero.objects.all().count() print(result8) ctx["result8"] = result8 return render(request,"select_hero_eight.html",ctx)