• DjangoORM


    一 Django ORM

      ORM. 对象关系映射
      作用:能够让一个不用sql语句的小白也能够通过python 面向对象的代码简单快捷的操作数据库
      不足之处:封装程度太高 有时候sql语句的效率偏低 需要你自己写SQL语句

    #1 先去models.py中书写一个类
    class User(models.Model):
        id = models.AutoField(primary_key=True,verbose_name='主键')
        username = models.CharField(max_length=32,verbose_name='用户名')
        password = models.CharField(verbose_name='密码',max_length=64)
    # 由于一张表中必须要有一个主键字段 并且一般情况下都叫id字段
    # 所以orm当你不定义主键字段的时候 orm会自动帮你创建一个名为id主键字段
    # 也就意味着 后续我们在创建模型表的时候如果主键字段名没有额外的叫法 那么主键字段可以省略不写

      数据库迁移命令

    python3 manage.py makemigrations 将操作记录记录到小本本上(migrations文件夹)
    
    python3 manage.py migrate  将操作真正的同步到数据库中
    # 只要你修改了models.py中跟数据库相关的代码 就必须重新执行上述的两条命令

    1.1 字段的增删改查

      字段的增加

        1.可以在终端内直接给出默认值

        2.该字段可以为空

    info = models.CharField(max_length=32,verbose_name='个人简介',null=True)

        3.直接给字段设置默认值

    hobby = models.CharField(max_length=32,verbose_name='兴趣爱好',default='study')

      字段的修改

        直接修改代码然后执行数据库迁移的两条命令即可!

      字段的删

        直接注释对应的字段然后执行数据库迁移的两条命令即可!执行完毕之后字段对应的数据也都没有了

      提醒

        在操作models.py的时候一定要细心,千万不要注释一些字段,执行迁移命令之前最好先检查一下自己写的代码

        个人建议:当你离开你的计算机之后一定要锁屏

    一 数据的增删改查

    1.1查看

    res = models.User.objects.filter(username=username)
    """
    返回值你先看成是列表套数据对象的格式
    它也支持索引取值 切片操作 但是不支持负数索引
    它也不推荐你使用索引的方式取值
    user_obj = models.User.objects.filter(username=username).first()
    """
    filter括号内可以携带多个参数 参数与参数之间默认是and关系
    你可以把filter联想成where记忆
     
    def userlist(request):
        # 查询出用户表里面所有的数据
        # 方式1
        data = models.User.objects.filter()
        # 方式2
        user_queryset = models.User.objects.all()
        return render(request,'userlist.html',locals())

    1.2 编辑

      """
      如何告诉后端用户想要编辑哪条数据?
          将编辑按钮所在的那一行数据的主键值发送给后端
          利用url问号后面携带参数的方式
          
          {% for user_obj in user_queryset %}
                            <tr>
                                <td>{{ user_obj.id }}</td>
                                <td>{{ user_obj.username }}</td>
                                <td>{{ user_obj.password }}</td>
                                <td>
                                    <a href="/edit_user/?user_id={{ user_obj.id }}" class="btn btn-primary btn-xs">编辑</a>
                                    <a href="" class="btn btn-danger btn-xs">删除</a>
                                </td>
                            </tr>
                        {% endfor %}
      """
      # 后端查询出用户想要编辑的数据对象 展示到前端页面供用户查看和编辑
      def edit_user(request):
        # 获取url问号后面的参数
        edit_id = request.GET.get('user_id')
        # 查询当前用户想要编辑的数据对象
        edit_obj = models.User.objects.filter(id=edit_id).first()
        if request.method == "POST":
            username = request.POST.get('username')
            password = request.POST.get('password')
            # 去数据库中修改对应的数据内容
            # 修改数据方式1
            # models.User.objects.filter(id=edit_id).update(username=username,password=password)
            """
                将filter查询出来的列表中所有的对象全部更新            批量更新操作
                只修改被修改的字段
            """
            # 修改数据方式2
            edit_obj.username = username
            edit_obj.password= password
            edit_obj.save()
            """
                上述方法当字段特别多的时候效率会非常的低
                从头到尾将数据的所有字段全部更新一边 无论该字段是否被修改
            """
            # 跳转到数据的展示页面
            return redirect('/userlist/')
        # 将数据对象展示到页面上
        return render(request,'edit_user.html',locals())

    1.3 删除

        跟编辑功能逻辑类似
        def delete_user(request):
        # 获取用户想要删除的数据id值
        delete_id = request.GET.get('user_id')
        # 直接去数据库中找到对应的数据删除即可
        models.User.objects.filter(id=delete_id).delete()
        """
            批量删除
        """
        # 跳转到展示页面
        return redirect('/userlist/')    
    # 真正的删除功能应该需要二次确认 我们这里先不做后面会讲
    # 删除数据内部其实并不是真正的删除 我们会给数据添加一个标识字段用来表示当前数据是否被删除了,如果数据被删了仅仅只是讲字段修改一个状态
      username       password       is_delete
      jason            123                0
      egon             123                1

    1.4 增加

    from app01 import models
    res = models.User.objects.create(username=username,password=password)
    # 返回值就是当前被创建的对象本身
    
    # 第二种增加
    user_obj = models.User(username=username,password=password)
    user_obj.save()  # 保存数据

    二 django orm中如何创建表关系

    图书表
    出版社表
    作者表
    作者详情表
    """
    图书和出版社是一对多的关系 外键字段建在多的那一方 book
    图书和作者是多对多的关系 需要创建第三张表来专门存储
    作者与作者详情表是一对一
    """
    from django.db import models
    # 创建表关系  先将基表创建出来 然后再添加外键字段
    class Book(models.Model):
        title = models.CharField(max_length=32)
        price = models.DecimalField(max_digits=8,decimal_places=2)
        # 总共八位 小数点后面占两位

       图书和出版社是一对多 并且书是多的一方 所以外键字段放在书表里面 publish = models.ForeignKey(to='Publish') # 默认就是与出版社表的主键字段做外键关联 """ 如果字段对应的是ForeignKey 那么会orm会自动在字段的后面加_id 如果你自作聪明的加了_id那么orm还是会在后面继续加_id 后面在定义ForeignKey的时候就不要自己加_id """ 图书和作者是多对多的关系 外键字段建在任意一方均可 但是推荐你建在查询频率较高的一方 authors = models.ManyToManyField(to='Author') """ authors是一个虚拟字段 主要是用来告诉orm 书籍表和作者表是多对多关系 让orm自动帮你创建第三张关系表 """ class Publish(models.Model): name = models.CharField(max_length=32) addr = models.CharField(max_length=32) class Author(models.Model): name = models.CharField(max_length=32) age = models.IntegerField() 作者与作者详情是一对一的关系 外键字段建在任意一方都可以 但是推荐你建在查询频率较高的表中 author_detail = models.OneToOneField(to='AuthorDetail') """ OneToOneField也会自动给字段加_id后缀 所以你也不要自作聪明的自己加_id """ class AuthorDetail(models.Model): phone = models.BigIntegerField() # 或者直接字符类型 addr = models.CharField(max_length=32) """ orm中如何定义三种关系 publish = models.ForeignKey(to='Publish') # 默认就是与出版社表的主键字段做外键关联 authors = models.ManyToManyField(to='Author') author_detail = models.OneToOneField(to='AuthorDetail') ForeignKey OneToOneField 会自动在字段后面加_id后缀 """ # 在django1.X版本中外键默认都是级联更新删除的 # 多对多的表关系可以有好几种创建方式 这里暂且先介绍一种 # 针对外键字段里面的其他参数 暂时不要考虑 如果感兴趣自己可以百度试试看

    三 django请求生命周期流程图(必会)

      

      扩展知识点:
      缓存数据库:提前已经将你想要的数据准备好了 你来直接拿就可以,提高效率和响应时间
      当你在修改你的数据的时候 你会发现数据并不是立刻修改完成的,而是需要经过一段时间才会修改:博客园
      了解即可

    四路由层

      4.1 路由匹配

      url方法第一个参数是正则表达式:只要第一个参数正则表达式能够匹配到内容 那么就会立刻停止往下匹配,直接执行对应的视图函数

    url(r'test',views.test),
    url(r'testadd',views.testadd)
    url中输入test或者testadd找到的都是test

      你在输入url的时候会默认加斜杠:django内部帮你做到重定向,一次匹配不行url后面加斜杠再来一次

    url(r'test/',views.test),
    url(r'testadd/',views.testadd)
    例:第一次testadd查找不到,url后面会加个/,然后就找到了

      取消自动加斜杠

    APPEND_SLASH = False/True    # 默认是自动加斜杠的,最好还是加斜杆

      在test前面后面输入一些乱七八糟的字符也能访问到test,解决方法用^和$    

    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        # 首页  url中输入127.0.0.1:8080先到首页
        url(r'^$',views.home),
        # 路由匹配
        url(r'^test/$',views.test),
        url(r'^testadd/$',views.testadd),
        # 尾页(了解)
        url(r'',views.error),
    ]

      4.2 无名分组

        分组:就是给某一段正则表达式用小括号扩起来

        无名分组就是将括号内正则表达式匹配到的内容当作位置参数传递给后面的视图函数

    url(r'^test/(d+)/',views.test)
    def test(request,xx):
        print(xx)
        return HttpResponse('test')

      4.3 有名分组

        可以给正则表达式起一个别名

        有名分组就是将括号内正则表达式匹配到的内容当作关键字参数传递给后面的视图函数

    url(r'^testadd/(?P<year>d+)',views.testadd) #  ?P<year>就是为d+匹配到的字符定义一个别名year
    def testadd(request,year):
        print(year)
        return HttpResponse('testadd')

      4.4 无名有名是否可以混合使用  

        不能混用,但是同一个分组可以使用N多次

    url(r'^index/(d+)/(d+)/(d+)/',views.index),
    url(r'^index/(?P<year>d+)/(?P<age>d+)/(?P<month>d+)/',views.index),

      4.5 反向解析

        通过一些方法得到一个结果 该结果可以直接访问对应的url触发视图函数

    #当前端页面有许多
    <a href="/func/"></a>
    <a href="/func/"></a>
    <a href="/func/"></a>
    <a href="/func/"></a>
    
    
    #一但urls.py中的url(r'^func/',views.func)要修改那么前端所有都要修改

        解决方法:

        先给路由与视图函数起一个别名

    url(r'^func/',views.func,name='ooo')

        后端反向解析

    from django.shortcuts import render,HttpResponse,redirect,reverse
    reverse('ooo')

        前端反向解析

    <a href="{% url 'ooo' %}">111</a>
  • 相关阅读:
    常用linux命令及其设置
    shell脚本编写步骤及其常用命令和符号
    浏览器访问php脚本通过sendmail用mail函数发送邮件
    windows server 定期备份数据库脚本
    图片垂直水平居中
    "!function",自执行函数表达式
    jQuery(function(){})与(function(){})(jQuery) 的区别
    在Windows Server 2019通过Docker Compose部署Asp.Net Core
    Redis集群同步问题
    webapi跨域使用session
  • 原文地址:https://www.cnblogs.com/bk134/p/12966481.html
Copyright © 2020-2023  润新知