• Python Day 58 Django框架、路由系统、视图函数、Django框架ORM框架(单表操作、一对多表、正反查询、双下划线方法)


      ##Django框架路由系统

    1、伪静态
        cnblogs:网站中的地址:
              https://www.cnblogs.c om/linhaifeng/articles/7133167.html
        自己项目中的访问地址:
            http://127.0.0.1:8000/up_studnet/?id=12
        
        如何实现?
            路由分发
    #2、路由分发
        url:
            url(r'^index/(w+)/(w+)/', index),
            url(r'^test/(?P<id>w+)/(?P<name>w+)/', test),
        对应函数:
        def index(request, name, id):
                print(id , name)
                return HttpResponse('index')
        def test(request, name, id):
                print(id , name)
                return HttpResponse('test')
        
        出现问题:
            1、index函数:在web端访问:
                http://127.0.0.1:8000/index/18/icon
                http://127.0.0.1:8000/index/icon/18
                会导致后台接收的id和name参数会随之变化
        解决方案:
            1、test函数:使用正则,然后起别名方式可以解决该问题
    #3、路由正则
        url(r'^test2/$', test2)   
        思路:使用正则,当出现访问的地址不存在时,返回浏览器自定义的not fund错误
        url(r'^', notfound)  需要写到最下面
    #4、反向路由:
    优点:
          设置反向路由以后,只需要修改后台连接地址就可以,无需要动前端代码
    后台url:
    url(r'^logindjsajdbjsabdsabdbsabdhsabdhbsahbdsaasa/$', login, name='xxx')  
        xxx为自定义
    
    前台:
    <form action="{% url 'xxx' %}">
         <input type="text">
    </form>

    反向解析(带参数的)
      url(r'^indexxasdaskkdjlksajdlksaj/(d+)/', index,name='index'),
      有名无名均按照下面方式使用即可:
        前端:{% url 'index' 1 %}
      后端:reverse('index',args=(1,))  #5、django创建app python3 manage.py startapp 自定义app名称 在settings.py配置文件中添加app02使其生效 INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', ‘app02’, ] app02参数介绍: admin.py : 写和django-admin相关的配置 apps: 对app的配置 models: 数据表模型 (********) tests: 测试 views: 视图函数 (*******#6、路由分组 浏览器访问:127.0.0.1:8000/app02/teachers 总:项目中urls.py; 先导入include from django.conf.urls import url,include 在路由分发中添加 url(r'^app02/', include('app02.urls')), url(r'^app03/', include('app03.urls')), 分:app02中urls.py: from app03 import views urlpatterns = [ url(r'^students/', views.studnets) ] 建议 大家使用:
      创建一个app, 然后在app的views.py中写自己的业务逻辑函数, urls.py 路由匹配, 只是进行分发

       ##Django框架视图函数

    
    

      我们之前写过的都是基于函数的view,就叫FBV。还可以把view写成基于类的。

    
    

      就拿我们之前写过的添加班级为例:


    #
    1、FBV:函数视图 function based view
      # FBV版添加班级
      def add_class(request):
          if request.method == "POST":
              class_name = request.POST.get("class_name")
              models.Classes.objects.create(name=class_name)
              return redirect("/class_list/")
          return render(request, "add_class.html")
    #2、CBV:类视图 class based view 总:项目中urls urlpatterns = [ url(r'^app03/',include('app03.urls')), ] 分:app03中urls from app03 import views urlpatterns = [ url(r'^login/',views.Login.as_view()), ] 分:app03中视图函数views from django.views import View class Login(View): def get(self,request): return render(request,'login.html') def post(self,request): uname = request.POST.get('username') print(uname) return HttpResponse('ok') 分:templates目录下login.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="/app03/login/" method="post"> <input type="text" name="username"> <input type="submit" value="tijiao"> </form> </body> </html> 浏览器:http://127.0.0.1:8000/app03/login/ get请求找类中get方法 post请求找类中post方法

      注意:

      使用CBV时,urls.py中也做对应的修改:
      # urls.py中
      url(r'^add_class/$', views.AddClass.as_view()),

    #3、给视图加装饰器
      FBV本身就是一个函数,所以和给普通的函数加装饰器无差:
      
    类中的方法与独立函数不完全相同,因此不能直接将函数装饰器应用于类中的方法 ,我们需要先将其转换为方法装饰器。
      Django中提供了method_decorator装饰器用于将函数装饰器转换为方法装饰器。
      如:
        # CBV版添加班级
        from django.views import View
        from django.utils.decorators import method_decorator

        class AddClass(View):

            @method_decorator(wrapper)
            def get(self, request):
                return render(request, "add_class.html")

            def post(self, request):
                class_name = request.POST.get("class_name")
                models.Classes.objects.create(name=class_name)
                return redirect("/class_list/") 
    #4、参数介绍
        'get': 请求数据
        'post':提交数据
        'delete': 删除数据
        'put': 更新数据
        'patch': 更新部分数据
    
        ps:
            form表单提交 只支持get、post  
            ajax支持多个
        
        核心:
                def dispatch(self, request, *args, **kwargs):
                    super(Login, self).dispatch(request, *args, **kwargs)
        dispatch方法:自定制的预处理操作:如权限管理,对登录时可以做一些预处理操作

       ##Django框架ORM

    #ORM配置
    """
    1、创建数据库
    2、配置mysql的数据库链接
        setting文件里的DATABASES设置为
        DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'NAME': 's8day61',    ## 数据库名称
            'USER': 'root',
            'PASSWORD': '123',    ## 安装 mysql 数据库时,输入的 root 用户的密码
            'HOST': '127.0.0.1',
        }
    3、注册app
        也是在settings文件中的INSTALLED_APPS
        把你的app文件名加进去
    4、需要把mysqldb设置为pymysql链接
        python3中用的是pymysql
        python2中使用的是mysqldb
        
        为了兼容,都改成pymysql
        app下的__init__文件
            import pymysql
            pymysql.install_as_MySQLdb()
    5、创建表(2个命令)
        
        python manage.py makemigrations  ## 生成migrations文件
        
        python manage.py migrate  ### 根据生成的migrations文件生成表
    
    """
    #案例:在app03中models.py建立模型表
    from django.db import models
    
    # Create your models here.
    class Department(models.Model):
        # 主键id  在django中会帮我们创建,所以可以省略id字段
        title = models.CharField(max_length=32,null=True)
    
    class Userinfo(models.Model):
        id = models.AutoField(primary_key=True)
        name = models.CharField(max_length=32,null=True)
        age = models.CharField(max_length=32,null=True)
        email = models.CharField(max_length=32,default="")
        # 默认会创建外键字段,字段名ud_id 回家一个_id
        ud = models.ForeignKey("Department",null=True)
    
    
    #注意
    模型表中的字段增删改查都需要刷新上述两个命令
    python3  manage.py makemigrations
    python3 manage.py migrate
    #单表的增删改查
    
    # 先导入models文件
    from class_app import models
     ### 增加
    # models.Department.objects.create(title="保安部")
    # models.Department.objects.create(title="开发部")
    
    ### 查询
    ### 查询所有 ==> 列表里套对象
    # res = models.Department.objects.all()
    ### <QuerySet [<Department: Department object>, <Department: Department object>]>
    # for row in res:
    #     print(row.id, row.title)
    
    ### 指定字段查询 values ==> 列表里套字典
    ### select title from department ;
    # res = models.Department.objects.values("title").all()
    # ### <QuerySet [{'title': '保安部'}, {'title': '开发部'}, {'title': '开发部'}]>
    # for row in res:
    #     print(row['title'])
    
    ### 指定字段查询 value_list==> 列表里套元组
    # res = models.Department.objects.values_list("title").all()
    # ### <QuerySet [('保安部',), ('开发部',), ('开发部',)]>
    # print(res)
    
    ### select * from xxx where title = "开发部"  过滤
    # res = models.Department.objects.filter(title='开发部').all()
    #
    # print(res)
    # res = models.Department.objects.filter(id__lt = 3)   ### less then 小于
    # res = models.Department.objects.filter(id__gt = 3)  ###  greater then 大于
    ## 取第一条数据
    # res = models.Department.objects.all().first()
    # print(res)
    #
    models.Classes.objects.filter(name="xxx").delete()
    
    #
    models.Classes.objects.filter(name="xxx").update(name="ooo")
    # 如果需要改的值很多,并且在一个字典里,也可以用**打散
    models.Classes.objects.filter(name="xxx").update(**dic)
    #一对多表 
       ### 增加
        # models.UserInfo.objects.create(uname = "icon", age=15, email="dddd@qq.com", ud_id=2)
        # models.UserInfo.objects.create(uname = "创彬", age=16, email="gggg@qq.com", ud_id=2)
        # models.UserInfo.objects.create(uname = "owen", age=18, email="hhhh@qq.com", ud_id=1)
    
        # info = {"uname":'zekai2', 'age':13, "email":'123@qq.com', "ud_id":2}
        # models.UserInfo.objects.create(**info)
    
    
        ### 查询
        ### 正向查询
        # res = models.UserInfo.objects.all()
        # for row in res:
        #     print(row.id, row.uname, row.age, row.ud.title)
    
        ### 反向查询
        ### 写法: 小写的表名_set.all()
        # res = models.Department.objects.all()
        # for row in  res:
        #     print(row.title, row.userinfo_set.all())
    
    
        ### 神奇的双下画线
        res = models.UserInfo.objects.values('id', 'uname', "ud__title").all()
        print(res)
    
        res = models.UserInfo.objects.values_list('id', 'uname', "ud__title").all()
        print(res)

      

    #django中orm的表的正查与反差
    
    # 如果一张表和其他的表建有外键关系,那么从这张表查另一张表称为正查,反之称为反差
    # 先建立两个外键关系的表
    class Classes(models.Model):    # 如果我们不设置一张表的id时,django会自动帮我创建一个自增的主键id
        name = models.CharField(max_length=32,null=True)
    
    class Students(models.Model):
        name = models.CharField(max_length=32,null=True)
        cid = models.ForeignKey("Classes",null=True)    # 会自动帮我们和另一张表的主键建立外键关系
    
    # 正查
    for obj in students:
        print(obj.cid.name)     # 可以直接通过对象点里面的属性就可以点出另一个类的对象,可以继续取值
    
    # 反查
    obj.student_set.all()       # 就是查出所有的对象
    
    # 还可以通过下划线直接取到另一张表的值
    # values是取出括号里对应的值,通过列表里套字典的形式
    # values_list 是取出括号里对应的值, 通过列表里套元组的形式
    models.Classes.objects.values("id","name","cid__name").all()
    #双下划线
    # 查询时通过外键名__另一张表的名字  可以查到关联表的值
    # eg:
    models.Classes.objects.values("id","name","cid__name").all()    #这个cid__name可以查询到关联表对应的name
    # 查询时可以在filter中加入限制条件  __lt 代表小于  __gt代表大于
    # eg:
    models.Classes.objects.filter(id__lt = 3).all()     # id < 3
    models.Classes.objects.filter(id__gte = 3).all()    # id >= 3

      

  • 相关阅读:
    远程连接Mysql报错 java.sql.SQLException:null,message from server ... is not allowed to connect
    使用 java.util.Properties 读取配置文件中的参数
    重载Prometheus配置
    Redis的 SLAVEOF 命令
    Redis为什么不能使用一主一从哨兵
    iptables添加开放端口
    解决172.17 或者172.18 机房环境下harbor服务器不通的问题
    利用sshpass批量导入ssh-key
    ZABBIX_PROXy
    zabbix_server.conf
  • 原文地址:https://www.cnblogs.com/liangzhenghong/p/11197092.html
Copyright © 2020-2023  润新知