Django框架学习02--模型实现数据库CRUL

一.基础复习

1.MVC模式 和 MVT模式:

MVC模式 MVT模式
M: ORM,通过模型的操作映射到数据库中 M: 数据存取层
V:页面,渲染给用户看的页面 V(views):业务逻辑
C:业务逻辑 T(template):模板,也就是页面
  1. 创建虚拟环境===virtualenv --no-site-packages -p

  2. django安装

    python3.7.0 —> 支持django2.0.7
    python3.6.x —> django 1.11

  3. 创建工程
    django-admin startproject day01

    包含的4个文件

    __init__.py
    import pymysql
    pymysql.installed_as_MySqldb===注意大小写
    __settings__.py配置信息

    例如:BASE_DIR====代码文件夹的路径
    
     INSTALLED_APP===创建的app要写在里面
    
     DATABASES===数据库信息
    

    __urls__.py 访问url,用来关联到视图里去的

    url(r'hello1/', views.helloworld)
    
    url(r'hello2/', views.helloworld)
    
    127.0.0.1:8000/hello/
    

    __uwsgi__.py 不用管

  4. 创建应用app===python manage.py startapp app1

    init.py
    apps.py==做管理后台用
    admin.py==没什么用
    test.py==做接口测试的
    models.py==定义模型的
    views.py==业务逻辑,视图函数
  5. 运行项目==python manage.py runserver

    python manage.py runserver 0.0.0.0:8080 启动端口和ip
    可以只写端口或者端口和ip都写python manage.py runserver 8080,但是不能只写ip

  6. 数据库迁移
    第一次:

    python manage.py migrate

    后面再次迁移:

    python manage.py makemigrations
    
    python manage.py migrate

    两个要联合使用

    8.管理后台==python manage.py createsupersuer

    用户名和密码, auth_user

    python manage.py createsupersuer

二.创建项目(巩固创建步骤)

1.进入虚拟环境文件夹:env/Script

2.激活虚拟环境===activate

【注】退出虚拟环境==deactivate

3.进入工程空间文件夹wordspace/django,创建项目

django-admin startproject day02

dir查看文件夹,day02创建成功

4.在day02中创建app,命名为app

python manage.py startapp app

在cmd和pycharm控制台都可以操作

5.配置pycharm项目环境

pycharm中打开项目day02,设置setting-->project interpreter设置我们环境文件夹位置env

三、工程文件基础设置

设置项目文件day02的子文件

1.init.py中初始化db

import pymysql

pymysql.install_as_MySQLdb()

2.settings.py文件设置

①在INSTALLED_APPS中添加上刚创建的app名字(刚命名的名字就叫app),不要忘记引号的逗号

INSTALLED_APPS = [
    ......
    'django.contrib.staticfiles',
    'app',
]

②数据库配置

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',    #改为mysql
        'NAME': '4day01',
        'USER': 'root',
        'PASSWORD': '123456',
        'HOST': '127.0.0.1',                 #写主机地址,例如云服务器地址等
        'PORT': 3306,                       #端口号
    }
}

【端口知识】

端口号范围:0-35535,几个默认端口(port)

FTP :21 HTTP:80 MySql:3306 Redis:6379

SQL Server :1433 oracal:1521 MongoDB :27017 ·

django启动:默认是8000

③语言、时区(默认是英语)

LANGUAGE_CODE = 'en-us'   ---->LANGUAGE_CODE = 'zh-hans' 

TIME_ZONE = 'UTC'        ----->Asia/Shanghai

四.app下文件设置——Url拆分

1.在app文件中新建url.py文件

目的:让app自己管理自己的路由,防止建立多个app时同时用工程下的urls.py文件

(1)导入url

from django.conf.urls import url

(2)将工程下的urls.py内容粘贴复制过来(括号路径内容先不写)

粘贴复制防止写错!!!

urlpatterns = [
    url()
]

(3)写一个方法,调用自己的视图view.py,

from django.conf.urls import url

from app import views        #要调用视图,就要导入视图

urlpatterns =[

    url(r'helloworld/', views.hello),     #使用views下面的hello方法,前面的helloworld是访问时需要
    ]

2.在视图view.py中定义方法

url返回的是view中的hello方法,所以要在view中取定义方法,这里定义一个hello方法,返回’hello world‘

from django.shortcuts import render
from django.http import HttpResponse   #要导入httpresponse,才会有响应

def hello(request):
    if request.method == 'GET':
        return HttpResponse('hello world')

五、关联工程下的url和app下的url

设置了app的url,想要有作用,必须和工程下的url有关联===include()

from django.conf.urls import url, include     #include需要导入
from django.contrib import admin
import app
urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'app/', include('app.urls')),      #app是我要网页中访问的时候需要输入的一部分,后面代表
                                        url的包含关系,两个url做了关联!不要落下引号

]

六、运行刚才页面==runserver

1.配置runserver

name:day02
scritpath:选中项目文件夹下对应的manage.py文件
parameters:runserver 8080(端口名)

2.运行

浏览器中打开,此时我们127.0.0.1:8080/app/helloworld/网页显示helloworld

系统会先找到工程下面的url(输入app),再找到app下的url(输入helloworld),找到对应的views下的hello方法,显示helloword

七、Django后台管理模型

1.定义模型—通过django操作数据库,模型就是一张表

通过对model的操作达到修改数据库 的效果

以学生表为例,学生信息包括学生姓名、性别、年龄班级

app文件夹下的models.py文件

class Student(models.Model):                        ## 定义一个学生模型
   s_name = models.CharField(max_length=10, unique=True) # charField写可变字符的,django是char类                                                     型,最大长度为10,unique代表是否为一
    s_age = models.IntegerField(default=16)         # IntegerField代表是int类型的,默认值是16
    s_sex = models.BooleanField(default=1)         # 性别定义为布尔类型,默认值是1

2.定义表名==命名为数据库名student

#定义数据库中表的名字
    class Meta:
        db_table = 'student'

3.数据迁移到数据库中

python manage.py makemigrations
python manage.py migrate

4.在数据库4day01中刷新表,产生一个新的数据库student

表中含有了id,s_name,s_age,s_sex字段

5.继续在model.py中设置数据库操作时间和创建时间字段,数据库这样就会自动生成和更新

用到模型字段DateTimeField

operator_time = models.DateTimeField(auto_now=True)
create_time = models.DateTimeField(auto_now_add=True)

6.数据迁移一下,在数据库中添加刚创建的时间字段

python manage.py makemigrations
python manage.py migrate

7.在app中的admin.py文件中写代码

目的是在django后台中导入模型,模型的名字是student

from django.contrib import admin
from app.models import Student

# 在后台导入模型,模型名字叫student
admin.site.register(Student)

此时登录django后台我们可以看到新增了学生student

这样就可以在后台对数据库进行操作了,这样就实现了没有写sql语句而是通过django后台完成了对表的增

8.例如我们从后台添加一个记录并保存:

名字:大锤;年龄:16

刷新一下sql表,会看到添加了一条记录,上面有创建时间和修改时间

9.【修改】在django后台将大锤年龄修改成15,刷新一下数据库表,创建时间没有修改,操作时间修改成刚才改年龄的时间

注意:

**(**1)一般情况下实际项目中一般不用django自带的后台

(2)对数据的增删改查就是对模型的操作

八、定义模型的字段

1.字段类型

字段类型
    ·AutoField
        ·一个根据实际ID自动增长的IntegerField,通常不指定如果不指定,一个主键字段将自动添加到模型中
    ·CharField(max_length=字符长度)
        ·字符串,默认的表单样式是 TextInput

    ·TextField
        ·大文本字段,一般超过4000使用,默认的表单控件是Textarea

    ·IntegerField 整数

    ·DecimalField(max_digits=None, decimal_places=None)
        ·使用python的Decimal实例表示的十进制浮点数
        ·参数说明
            ·DecimalField.max_digits
                ·位数总数
            ·DecimalField.decimal_places
                ·小数点后的数字位数

    ·FloatField
        ·用Python的float实例来表示的浮点数

    ·BooleanField
        ·true/false 字段,此字段的默认表单控制是CheckboxInput

    ·NullBooleanField
        ·支持nulltruefalse三种值

 DateField([auto_now=False, auto_now_add=False])
        ·使用Python的datetime.date实例表示的日期
        ·参数说明
        DateField.auto_now每次保存对象时,自动设置该字段为当前时间,用于"最后一次修改"的时间戳,它                           总是使用当前日期,默认为false
        ·DateField.auto_now_add
        ·当对象第一次被创建时自动设置当前时间,用于创建的时间戳,它总是使用当前日期,默认为false
·说明
·该字段默认对应的表单控件是一个TextInput. 在管理员站点添加了一个JavaScript写的日历控件,和一个“Today"的快捷按钮,包含了一个额外的invalid_date错误消息键
·注意
·auto_now_add, auto_now, and default 这些设置是相互排斥的,他们之间的任何组合将会发生错误的结果

    ·TimeField ·使用Python的datetime.time实例表示的时间,参数同DateField

    ·DateTimeField ·使用Python的datetime.datetime实例表示的日期和时间,参数同DateField

    ·FileField ·一个上传文件的字段

    ·ImageField ·继承了FileField的所有属性和方法,但对上传的对象进行校验,确保它是个有效的image

2.字段选项

·通过字段选项,可以实现对字段的约束;·在字段对象时通过关键字参数指定

·null  ·如果为True,则该字段在数据库中是空数据,默认值是 False

·blank  ·如果为True,则该字段允许为空白,默认值是 False

【注意】
·null是数据库范畴的概念,blank是表单验证证范畴的
·db_column  ·字段的名称,如果未指定,则使用属性的名称
·db_index   ·若值为 True, 则在表中会为此字段创建索引

·default ·默认值

·primary_key  ·若为 True, 则该字段会成为模型的主键字段

·unique   ·如果为 True, 这个字段在表中必须有唯一值

九.ORM概念(Objects Relational Mapping)

ORM—关系映射,可以翻译成数据库语句,用于实现面向对象编程语言里不同系统数据之间的数据转换

django ORM 数据库
增删改查 get, all, fiter mysql, oracle ,sqlite

十.用Django实现数据库CRUD

在模型model中中定义好内容,实现对数据库的增删改查

1.准备工作:

(1)在设置好路由在app的urls.py中(也可以不进行url拆分直接放到项目下的url中)

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url('create_stu/', views.create_stu),
    url('select_stu', views.select_stu),
    url('delete_stu', views.delete_stu),
    url('update_stu', views.update_stu),
]

(2)在model中定义一个学生模型

from django.db import models


# 定义一个模型,
class Student(models.Model):
    # 定义两个字段,注释不受影响
    s_name = models.CharField(max_length=10, unique=True)
    s_age = models.IntegerField(default=16)
    s_sex = models.BooleanField(default=1, verbose_name='性别')

    create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
    operate_time = models.DateTimeField(auto_now=True, verbose_name='修改时间')

    # 定义数据库中的表的名字,如果不定义别名默认是app_student(就是app名字+模型名)
    class Meta:
        db_table = 'student'

2.增加数据(Views.py中操作)

在views中写入方法(刚才url需要获取的)

from django.http import HttpResponse
from django.shortcuts import render

from app.models import Student


def create_stu(request):
    # 三种方式:
    # 方式一: 通过模型创建学生信息,性别和年龄会选择之前设置的默认值
    # Student.objects.create(s_name='小草')
    # Student.objects.create(s_name='小明')
    # Student.objects.create(s_name='小赵')
    # Student.objects.create(s_name='小钱')
    # Student.objects.create(s_name='小孙')
    # Student.objects.create(s_name='小李')
    # Student.objects.create(s_name='小周')
    # Student.objects.create(s_name='小吴')

    # 创建方式二;save()方法,创建创建s_name属性,这种方式不能一次创建多条
    # 先拿到对象Student()
    stu =Student()
    stu.s_name = '李逵'
    stu.save()

    # 创建方式三:初始化方式(不常用,容易出错),现在model中初始化方法
    # stu = Student('兰陵王',20,1)
    # stu.save()
    return HttpResponse('创建学生成功')


    【方法三model]中设置
    设置age和sex为空,这样可以给他们默认值
    def __init__(self,name,age=None,sex=None):
        self.s_name = name
        # 三元运算符
        self.s_age = age if age else self.s_age
        self.s_sex = sex if sex else self.s_sex
        self.create_time = datetime.now()
        self.operate_time = datetime.now()

3.查询数据

先回顾一下sql语句的写法sql = ‘select * from student’,这里我们不用sql语句了,

Django默认通过模型的objects对象实现模型数据查询,Student.objects.all()

1.用For循环来获取查询的结果

首先我们先在pycharm的控制台演示

def select_stu(request):
    # 查询所有
    stus = Student.objects.all()
    # 获取信息
    for stu in stus:
        print(stu.s_name)
    return HttpResponse('查询学生信息')

   刷新一下页面可以从控制台看到学生姓名信息(debug中),换行打印出来

接下来我们想要引用列表推导式来获取学生信息试一下,可以拿到所有学生信息的集合

用两种方式:

方式一:简写模式

def select_stu(request):
    # 查询所有
    stus = Student.objects.all()
    # 获取信息
    stu_names =[stu.s_name for stu in stus ]
    print(stu_names)
    return HttpResponse('查询学生信息')

方式二:用append方法

def select_stu(request):
    # 查询所有
    stus = Student.objects.all()
    names = []
    for i in stus:
        names.append(i.s_name)
    print(names)
    return HttpResponse('查询学生信息')

2.查询知识点

我们查所有的可以循环遍历拿到,那么我们要有选择性的获取信息,就需要过滤器、条件查询、模糊查询等这些知识。

运行的时候用debug模式来查询效果,在控制台查看

查询数据
            all :查询所有数据

  过滤器:          
            filter:获取的结果为queryset(查询集),结果可以返回空,一个或多个对象。
                    filter可以多条件查询,连写点操作,也可以直接在括号中写多个条件
            get() 获取的结果为object(单个)对象,如果没有满足条件的对象获取会报错,
                   获取的对象超过一个也会报错
            注意:get()能不用就不用,最后就不要用


            exclude :不包含    获取不包含该对象以外的所有对象
            order_by :排序  +:升序   -:降序
            values-->获取单个字段
            first:获取queryset(查询集)中的第一个对象
            last:获取queryset(查询集)中的最后一个对象
    切片--->前面那个下标要考虑取值范围,后面那个不用
   模糊查询:contains==>'%x%'    startswith==>'x%'   endswith==>'%x'
            isnull/isnotnull 判断是否为空/是否不为空
            in  判断在范围之内
            pk:primary key主键
   比较运算:gt(大于) gte(大于等于) lt(小于) lte(小于等于)
   逻辑运算:Q(条件) | Q(条件) 逻辑或 ;Q(条件) & Q(条件) 逻辑与  ;~Q(条件) 逻辑非

实例

def select_stu(request):
        '''
        【filter和get区别】
        filter:获取结果为queryset,可以获取多条数据,获取不成功返回空
        get:返回对象,返回多个报错!获取不到数据会报错

        #查询数据sql语句
        # select * from app_sudent;
        stus =Student.objects.all()

        # filter过滤查询:查询年龄为19的学生,若有多个值都会显示
        # filter获取一个值能拿到,获取多个值能拿到,获取没有的值返回空
        stus = Student.objects.filter(s_age = 19)
        # 过滤查询:查询名字为小明的
        stus = Student.objects.filter(s_name = '小明')

        # get()方法:查询年龄为19的
        # get方法获取多个值会报错!
        # stus = Student.objects.get(s_age = 19)

 # 多条件查询
        stus = Student.objects.filter(s_age = 19, s_name ='小明')
        stus = Student.objects.filter(s_age = 19).filter(s_name = '小明')

        # 查询不包含 exclude
        # 查询姓名不为小明的数据
        stus = Student.objects.exclude(s_name = '小明')

 # 排序,按照id升序、降序==》asc/desc
        stus = Student.objects.all().order_by('id')
        stus = Student.objects.all()


 #values()
        stus = Student.objects.all().values()
        #get() first()的使用区别
        #first()方式获取不到返回null,用get()方法获取不到会报错
        stus = Student.objects.get(id=1)
        stus = Student.objects.filter(id=1).first()
#first() last()
        stus = Student.objects.all().order_by('id').last()
        # 通过切片获取,直接写下标[n]若不存在会报错
        # 可以写成[n:]或[:n]
        stus = Student.objects.all().order_by('-id')[:12]

        #模糊查询:查询名字中带有花的学生的信息
        stus = Student.objects.filter(s_name__contains='花')

        #查询以花开头的数据
        stus = Student.objects.filter(s_name__startswith='花')
        #查询以花结束的,sql
        stus = Student.objects.filter(s_name__endswith='花')

        # in 判断在范围之内
        # stus=Student.objects.filter(id__in=[1,2,6])


        #运算符 gt,gte,lt,lte:大于、大于等于、小于、小于等于
        #查询年龄大于18的数据
        stus = Student.objects.filter(s_age__gt=18)

        #PK: primary key主键


       Q函数
        # Q(),且、或、非操作
        # 查询姓名叫小花的,或者年龄为18
        # stus=Student.objects.filter(Q(s_name='小李') | Q(s_age=20))
        # stus = Student.objects.filter(Q(s_name='小李') & Q(s_age=20))
        # 查询姓名不叫小花的,或者年龄为18
        # stus = Student.objects.filter(~Q(s_name='小李') | Q(s_age=20))


        #获取学生姓名
        # stu_names = [stu.s_name for stu in stus]
        # print(stu_names)
        # return HttpResponse('查询学生信息')

4.删除数据

def delete_stu():
        stu = Student.objects.filter(pk=1).first()
        stu = Student.objects.get(pk=1)
        stu.delete()
        return HttpResponse('删除')

5.更新数据

一共两种方法,一个简写,一个连写

def update_stu():
        #更新方法一:
        stu = Student.objects.filter(id=1).update(s_name='哈哈')
        #方法二:
        stu = Student.objects.get(id=1)
        stu.s_name ='悟空'
        return  HttpResponse('修改')

【注:python断点调试】

用debug模式运行到红点位置会终止程序运行,防止后面的程序不确定是否有错误时候报错

猜你喜欢

转载自blog.csdn.net/ZZQHELLO2018/article/details/82632455