zoukankan      html  css  js  c++  java
  • 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

      

  • 相关阅读:
    PHP 开发 APP 接口 学习笔记与总结
    Java实现 LeetCode 43 字符串相乘
    Java实现 LeetCode 43 字符串相乘
    Java实现 LeetCode 43 字符串相乘
    Java实现 LeetCode 42 接雨水
    Java实现 LeetCode 42 接雨水
    Java实现 LeetCode 42 接雨水
    Java实现 LeetCode 41 缺失的第一个正数
    Java实现 LeetCode 41 缺失的第一个正数
    Java实现 LeetCode 41 缺失的第一个正数
  • 原文地址:https://www.cnblogs.com/liangzhenghong/p/11197092.html
Copyright © 2011-2022 走看看