zoukankan      html  css  js  c++  java
  • Django之orm

    一、Django静态文件配置

    ##settings.py##
    静态文件配置:
    STATIC_URL = '/static/'
    
    # 静态文件配置
    STATICFILES_DIRS = [
        os.path.join(BASE_DIR,'static')
    ]
    # 暴露给外界能够访问服务器静态文件夹下面所有的资源
    
    
    STATIC_URL = '/xxx/'      # 接口前缀 跟你的静态文件夹的名字一点关系都没有
                # 默认情况下这个前缀跟静态文件夹名字一样!!!
    
    # 静态文件配置
    STATICFILES_DIRS = [
        os.path.join(BASE_DIR,'static'),  # 就是你的静态文件夹路径
        os.path.join(BASE_DIR,'static1'),
        os.path.join(BASE_DIR,'static2')
    ]
    
    # ps:会依次查找列表中所有的静态文件路径 找到的话立刻停止,都没有找到返回404


    静态文件目录结构:
    项目目录-->static-->{css, js, images, bootstrap-3.3.7}
    
    
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
        <link rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.min.css">
        <script src="/static/bootstrap-3.3.7/js/bootstrap.min.js"></script>
    </head>


    二、form表单提交数据的动作两种方式

    <input  type='submit'>
    <button></button>


    三、form提交数据的地址如何指定及方式

    action属性控制提交的地址:
    方式:
        1.全路径
            <form action="http://127.0.0.1:8000/login/">
        2.只写路径后缀
            <form action="/login/">
        3.不写 (默认往当前路径提交)
    
    form表单默认是get请求;


    四、案例-根据客户端请求方式的不同执行不同的逻辑代码

    根据客户端请求方式的不同执行不同的代码:
    def login(request):         
        print(request.method)   #获取用户提交的请求方式,全是大写的字符串
        if request.method == 'GET':
            return render(request,'login.html') #get的话返回登录页面
        return HttpResponse('ok')   #如果是post的话进行其他操作


    def login(request):
    # 获取用户端提交的请求方式
    print(request.method)  # 拿到的请求方式是全大写的字符串
    
    if request.method == 'POST':
        print(request.POST)  # 你就把它当成一个大字典里面存放了客户端post提交的所有的数据
        # request.POST:< QueryDict: {'username': ['jason'], 'password': ['123']} >
        print(request.POST.get('username'))  # value虽然是个列表但是获取value的时候拿到却是单个元素
        # 默认只会取value列表里面的最后一个元素
        # request.POST:<QueryDict: {'username': ['jason', 'egon'], 'password': ['123']}>
        print(request.POST.getlist('username'))  # 要想一次性获取value列表里面所有的数据需要用getlist()
        # ['jason', 'egon']
        print(request.POST['password'])  # 不推荐使用该方法获取数据
        return HttpResponse('OK')
    return render(request,'login.html')
    
    获取value列表里面所有的元素需要使用getlist  应用场景:用户的爱好 多选框;
    get只会获取到value列表的最后一个元素;


    五、django连接数据库

    1、需要修改配置文件

    ##settings.py##
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'NAME': 'day55',
            'HOST': '127.0.0.1',
            'PORT': '3306',
            'USER': 'root',
            'PASSWORD': '123456',
        }
    }
    
    ps:键必须都是大写


    2.告诉django用pymysql替换它默认mysqldb模块连接数据库

    方式1:在你的项目文件夹下面的__init__.py
    方式2:也可以在你的应用文件夹下面的__init__.py
    写入一下两行:
            
    # 固定写法
    import pymysql
    pymysql.install_as_MySQLdb()  # 告诉django用pymysql代替mysqldb连接数据库


    六、ORM

    1、ORM简介

    ORM 全拼Object-Relation Mapping.
    对象关系映射;
    
    类        》》》  表
    对象           》》》  表记录
    对象的属性      》》》 一条记录某个字段对应的值
    
    django的orm不能够自动创建库,但是可以自动帮你创建表
    
    提示:一个django项目就使用一个库,不要多个django项目使用一个库


    2、ORM优缺点

    优点:
    (1)只需要面向对象编程, 不需要面向数据库编写代码.
        对数据库的操作都转化成对类属性和方法的操作.
        不用编写各种数据库的sql语句.
    
    (2)实现了数据模型与数据库的解耦, 屏蔽了不同数据库操作上的差异.
        不在关注用的是mysql、oracle...等.
        通过简单的配置就可以轻松更换数据库, 而不需要修改代码.
    
    
    缺点:
    相比较直接使用SQL语句操作数据库,有性能损失.
    根据对象的操作转换成SQL语句,根据查询的结果转化成对象, 在映射过程中有性能损失.


    2、数据库同步

    ##models.py##
    
    当models.py文件有改动时,就要在项目目录中执行下列两个命令;
    
    python3 manage.py makemigrations  将你的数据库变动记录到一个小本本上(并不会帮你创建表)
    python3 manage.py migrate         将你的数据库变动正在同步到数据库中


    七、ORM使用

    1、字段类型

    示例:
    class User(models.Model):
        id = models.AutoField(primary_key=True)
        name = models.CharField(max_length=32)
        password = models.CharField(max_length=16)
        addr = models.CharField(max_length=32, default='China')
    
    
    
    属性名 = models.字段类型,定义属性时需要指定字段类型, 通过字段类型的参数指定选项
    
    属性名:
        不允许使用python的保留关键字
        不允许使用mysql的保留关键字
        不允许使用连续的下划线,因为Django的查询语法就是连续的下划线
        
    AutoField:自动增长的IntegerField, 不指定时Django会自动创建属性名为id的自动增长属性
    BooleanField:布尔字段,值为True或False
    NullBooleanField:支持Null、True、False三种值
    CharField(max_length=20):字符串
        参数max_length表示最大字符个数
        
    TextFiled:大文本字段,一般超过4000个字符时使用
    IntegerField:整数
    DecimalField(max_digits=None, decimal_places=None):可以指定精度的十进制浮点数
        参数max_digits表示总位数
        参数decimal_places表示小数位数
    
    FloatField():浮点数  DateField[auto_now=False, auto_now_add=False]):日期
        参数auto_now表示每次保存对象时,自动设置该字段为当前时间,用于"最后一次修改"的时间戳,它总是使用当前日期,默认为false
        参数auto_now_add表示当对象第一次被创建时自动设置当前时间,用于创建的时间戳,它总是使用当前日期,默认为false
        参数auto_now_add和auto_now是相互排斥的,组合将会发生错误
    
    TimeField:参数和DateField一样
    DateTimeField:日期时间,参数同DateField
    FileField:上传文件字段,以二进制的形式
    ImageField:继承于FileField,对上传的内容进行校验,确保是有效的图片


    2、字段选项

    null:如果为True,表示允许为空,默认值是False
    blank:如果为True,则该字段允许为空白,默认值是False     对比:null是数据库范畴的概念,blank是表单验证范畴的
        
    db_column:字段的名称,如果未指定,则使用属性的名称(只限于数据库表中的名字,操作数据库还是类属性的名字)
    db_index:若值为True, 则在表中会为此字段创建索引,默认值是False(为了优化查询速度 )
    default:默认值,这可以是值或可调用对象。如果可调用,则每次创建新对象时都会调用它。
    primary_key:若为True,则该字段会成为模型的主键字段,默认值是False,一般作为AutoField的选项使用
    unique:如果为True, 这个字段在表中必须有唯一值,这个值不能重复,默认值是False
    
    关系型字段类型:关联表中使用:
    注意:Django会自动为表创建主键字段
        如果使用选项设置某属性为主键字段后,Django不会再创建自动增长的主键字段
        默认创建的主键字段为id,可以使用pk代替,pk全拼为primary key


    3、关系字段类型

    关系型数据库的关系包括三种类型:
        ForeignKey:一对多,将字段定义在多的一端中
        ManyToManyField:多对多,将字段定义在任意一端中
        OneToOneField:一对一,将字段定义在任意一端中
        
    可以维护递归的关联关系,使用self指定


    4、元选项

    作用:修改数据库表的默认的名称
    
    数据库表的默认名称为 :  
        应用名_模型名
        如:应用名:app01   模型类:User
        则表名为:app01_user
    
    
      class BookInfo(models.Model):
          name = models.CharField(max_length=20)   #图书名称
     
          class Meta: #元信息类
              db_table = 'bookinfo' #自定义表的名字


    八、Django数据库的操作

    from django.shortcuts import render,HttpResponse,redirect
    import pymysql
    from app01 import models
    
    # Create your views here.
    def login(request):
        # 获取用户端提交的请求方式
        print(request.method)  # 拿到的请求方式是全大写的字符串
        # if request.method == 'GET':
        #     return render(request,'login.html')
        # elif request.method == 'POST':
        #     return HttpResponse("收到了 老弟")
        if request.method == 'POST':
            # print(request.POST)  # 你就把它当成一个大字典里面存放了客户端post提交的所有的数据
            # # request.POST:< QueryDict: {'username': ['jason'], 'password': ['123']} >
            # print(request.POST.get('username'))  # value虽然是个列表但是获取value的时候拿到却是单个元素
            # # 默认只会取value列表里面的最后一个元素
            # print(request.POST.getlist('username'))  # 要想一次性获取value列表里面所有的数据需要用getlist()
            # print(request.POST['password'])  # 不推荐使用该方法获取数据
            # 获取用户输入的用户名和密码
            username = request.POST.get('username')
            password = request.POST.get('password')
            conn = pymysql.connect(
                host='127.0.0.1',
                port = 3306,
                user = 'root',
                password = '123',
                database = 'day54',
                charset = 'utf8',
                autocommit = True
            )
            cursor = conn.cursor(pymysql.cursors.DictCursor)
            cursor.execute('select * from userinfo where name=%s and password=%s',(username,password))
            user_info = cursor.fetchall()
            if user_info:
                return HttpResponse('登录成功')
        # print(request.GET)  # <QueryDict: {'username': ['jason'], 'password': ['123']}>
        # # 获取get请求数据的方式跟post请求完全一样!!!
        return render(request,'login.html')
    
    
    def reg(request):
        if request.method == 'POST':
            # 获取用户输入的用户名和密码
            username = request.POST.get('username')
            password = request.POST.get('password')
            # 操作数据库user表插入数据
            # 方式1:
            # user_obj = models.User.objects.create(name=username,password=password)
            # 方式2:
            user_obj = models.User(name=username,password=password)
            user_obj.save()  # 对象调用save方法保存到数据库
            print(user_obj.pk)  # pk获取主键字段对应的值  无论的你主键叫什么名字
            print(user_obj.name)  # 获取用户数据的name值
            print(user_obj.password)  # 获取用户数据的password值
            return redirect('/userlist/')
        return render(request,'reg.html')
    
    def userlist(request):
        # 获取数据库数据
        user_list = models.User.objects.all()  # select id,name,password form user;
        # print(user_list.query)  # 只要是QuerySet就可以点query查看获取到当前QuerySet对象的内部sql语句
        # for user_obj in user_list:
        #     print(user_obj.pk,user_obj.name)
        return render(request,'userlist.html',locals())
    
    def delete_user(request):
        # 从get请求携带的参数中获取用户想要删除的数据id
        delete_id = request.GET.get('delete_id')
        # res = models.User.objects.filter(id=1)[0]
        # res = models.User.objects.filter(id=1).first()
        models.User.objects.filter(id=delete_id).delete()  # 会将queryset所有的数据对象全部删除
        # print(res)  # <QuerySet [<User: jason>]>
        # # print(res.query)
        # print(type(res))
        return redirect('/userlist')
    
    
    def edit(request):
        if request.method == 'POST':
            print(request.POST)
            print(request.GET)
            username = request.POST.get('username')
            password = request.POST.get('password')
            # 获取编辑对象的id方式
            edit_id = request.POST.get('edit_id')
    
            edit_id = request.GET.get('edit_id')
            # 更新数据库
            models.User.objects.filter(id=edit_id).update(name=username,password=password)
            return redirect('/userlist')
        # 获取用户想要修改的数据的id
        edit_id = request.GET.get('edit_id')
        # 将该数据查询出来渲染到一个编辑页面
        # 查询数据方式1
        user_obj = models.User.objects.filter(id=edit_id).first()
        # 查询数据方式2
        # # user_obj = models.User.objects.get(id=edit_id)
        # print(user_obj,type(user_obj))
        # 将当前数据渲染到一个编辑页面上
    
        return render(request,'edit.html',locals())


    九、a标签href属性

    利用a标签href属性 可以指定页面跳转的路径  href可以写全路径 但是推荐写后缀即可:
    <a href="/reg/" class="btn btn-success">添加数据</a>
     <a href="/edit/?edit_id={{ user_obj.pk }}" class="btn btn-primary">编辑</a>
     <a href="/delete_user/?delete_id={{ user_obj.pk }}" class="btn btn-danger">删除</a>
    
    # 注意 路径的书写一定要加斜杠


    十、表单元素input type=”hidden”

    隐藏域在页面中对于用户是不可见的,在表单插入中隐藏域的目的在于收集和发送信息,以利于被处理表单的程序所使用 
    注:隐藏只是在网页页面上不显示输入框,但是虽然隐藏了,还是具有form传值功能。一般用来传值,而不必让用户看到。
    
    基本语法:
    <input type="hidden" name="field_name" value="value" />
    
    
    <div class="container">
        <div class="row">
            <h1>编辑数据</h1>
            <div class="col-md-6 col-md-offset-3">
                <form action="/edit/?edit_id={{ user_obj.pk }}" method="post">
                    <input type="hidden" name="edit_id" value="{{ user_obj.pk }}">
                    <p>username:<input type="text" name="username" value="{{ user_obj.name }}" class="form-control"></p>
                    <p>password:<input type="text" name="password" value="{{ user_obj.password }}" class="form-control"></p>
                    <input type="submit" class="btn btn-warning">
                </form>
            </div>
        </div>
    </div>
    
    
    def edit(request):
        if request.method == 'POST':
            print(request.POST)
            print(request.GET)
            username = request.POST.get('username')
            password = request.POST.get('password')
            # 获取编辑对象的id方式
            edit_id = request.POST.get('edit_id')
    
            edit_id = request.GET.get('edit_id')
            # 更新数据库
            models.User.objects.filter(id=edit_id).update(name=username,password=password)
            return redirect('/userlist')
        # 获取用户想要修改的数据的id
        edit_id = request.GET.get('edit_id')
        # 将该数据查询出来渲染到一个编辑页面
        # 查询数据方式1
        user_obj = models.User.objects.filter(id=edit_id).first()
        # 查询数据方式2
        # # user_obj = models.User.objects.get(id=edit_id)
        # print(user_obj,type(user_obj))
        # 将当前数据渲染到一个编辑页面上
    
        return render(request,'edit.html',locals())
  • 相关阅读:
    Sql:主表与子表的最新记录级联查询
    发现eclipse红叉,查看markers发现Target runtime Apache Tomcat 6.0 is not defined
    The required Server component failed to start so Tomcat is unable to start问题解决
    Spring官网下载dist.zip的几种方法
    SPRING---------配置文件的命名空间
    eclipse中egit插件使用
    eclipse不自动弹出提示(alt+/快捷键失效)
    使用jenkins配置.net mvc网站进行持续集成
    windows系统的便签
    Linq to Entity 动态拼接查询条件(重点是OR)
  • 原文地址:https://www.cnblogs.com/weiyiming007/p/11777411.html
Copyright © 2011-2022 走看看