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)

 

posted @ 2020-03-12 18:58  旅行没有终点  阅读(226)  评论(0编辑  收藏  举报