• Django整体架构


    Django整体架构

    • 用户能够访问到的所有的资源 都是程序员提前暴露好的, 如果没有暴露 用户就永远访问不了
    • 用户能够访问到的所有的资源 都是程序员提前暴露好的, 如果没有暴露 用户就永远访问不了

    一、响应请求的三种方式

    首先导入模块:from django.shortcuts import render,HttpResponse,redirect

    1.1 HttpResponse

    HttpResponse("响应页面内容")

    # 1. 首先在urls.py配置请求路径
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^httpresponse/', views.httpresponse),
    ]
    
    # 2. 编写对应函数
    def httpresponse(request):
        return HttpResponse("我是HttpResponse")
    
    # 3. 浏览器中请求
    http://127.0.0.1:8000/httpresponse
    

    我是HttpResponse

    1.2 render

    render:返回html窗体内容

    1. 返回html内容
    # 1. 首先在urls.py配置请求路径
    from app01 import views
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^httpresponse/', views.httpresponse),
        url(r'^renders/', views.renders),
    ]
    
    
    # 2. 编写对应函数
    def renders(request):
        return render(request, "02render.html")
    
    # 3. 浏览器中请求
    http://127.0.0.1:8000/renders
    

    我是render

    2. 在html中通过字典获取后台数据**
    <!--02render.html-->
    <!DOCTYPE html>
    
    <body>
    <h1>我是render</h1>
    {{ user }}
    </body>
    </html>
    
    # 1. 首先在urls.py配置请求路径
    from app01 import views
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^httpresponse/', views.httpresponse),
        url(r'^renders/', views.renders),
    ]
    
    
    # 2. 编写对应函数
    def renders(request):
        user_info = {"user": "randy", 'age': 18}
        # 注意:只能返回的是字典数据类型,其他数据类型则会报错
        return render(request, "02render.html", {'user': user_info})
    # 3. 浏览器中请求
    http://127.0.0.1:8000/renders
    

    我是render

    {"user": "randy", 'age': 18}

    3. locals获取所有局部变量**
    <!--02render.html-->
    <body>
    {{ user_info }}<br>
    locals可以获取当前所有局部变量:{{ num }} <br>
    locals可以获取当前所有局部变量:{{ count }} <br>
    </body>
    </html>
    
    # 1. 首先在urls.py配置请求路径
    from app01 import views
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^httpresponse/', views.httpresponse),
        url(r'^renders/', views.renders),
    ]
    
    # 2. 编写对应函数
    def renders(request):
        user_info = {"user": "randy", 'age': 18}   
        num=123
        count = 890
        # locals返回全部局部变量
        return render(request, "02render.html", locals())
    # 3. 浏览器中请求
    http://127.0.0.1:8000/renders
    

    {'user': 'randy', 'age': 18}
    locals可以获取当前所有局部变量:123
    locals可以获取当前所有局部变量:890

    4. 获取后台数据的两种方式的比较
    • 通过字典的方式传送数据,当传送多个数据编写困难,相对于locals效率高些
    • 通过locals会把前名称空间中所有变量全部传送到页面中,效率相对字典底

    1.3. redirect

    redirect:重定向另一个页面

    # 1. 首先在urls.py配置请求路径
    from app01 import views
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^httpresponse/', views.httpresponse),
        url(r'^renders/', views.renders),
        url(r'^redirects/', views.redirects),
    ]
    
    # 2. 编写对应函数
    
    def redirects(request):
        print(request)
        # return redirect('/index') # 重定向指定的路径
        return redirect("https://www.baidu.com") # 重定向到指定的url
    # 3. 浏览器中请求
    http://127.0.0.1:8000/redirects  # 进入百度页面
    
    • 三者都需return,返回都是httpresponse对象
    • rendirect重定向带数据
    • render不带数据

    二、 静态文件配置

    引用css,js,第三方框架的时候,需要配置静态文件,否则页面将没有被渲染,

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <!--static不是文件,是静态资源访问的接口-->
        <script src="/static/bootstrap/js/jquery.js"></script>
        <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.css">
        <script src="/static/bootstrap/js/bootstrap.min.js"></script>
    </head>
    <body>
    <h1>static</h1>
    </body>
    </html>
    

    通常情况下 网站所用到的静态文件资源 统一都放在static文件夹下,并且需要在setttings.py 中 手动配置静态文件访问的资源,如下

    STATIC_URL = '/static/'  # 是访问静态资源的接口前缀
    """只要你想访问静态资源 你就必须以static开头"""
    
    # settings.py配置,名字不可以更改
     STATICFILES_DIRS = [
         	# 添加静态文件可以添加多个,拼接文件夹的路径
            os.path.join(BASE_DIR,'static'),
            os.path.join(BASE_DIR,'static1'),
            # os.path.join(BASE_DIR,'static2'),
        ]
    

    注意:

    STATIC_URL = '/static/' # 是访问静态资源的接口前缀中static并不是你创建文件夹的名称,而是一个静态资源访问接口,名字是可以改变的,为避免修改static的修改,在引用js,css可以动态设置

    接口前缀 动态解析静态文件
    {% load static %}
    <link rel="stylesheet" href="{% static '/bootstrap/css/bootstrap.css' %}">
    <script src="{% static '/bootstrap/js/bootstrap.min.js' %}"></script>
    

    三、 form表单

    from表单默认项后台提交的方式默认为get请求,get请求携带带参数的方式是在url的后面url?username=admin&password=213213213213213, 从而导致提交数据不安全,并且它携带的杉树大小有限制,一般采用post请求

    # 采用post请求暂且要注释一个中间件
        MIDDLEWARE = [
                'django.middleware.security.SecurityMiddleware',
                'django.contrib.sessions.middleware.SessionMiddleware',
                'django.middleware.common.CommonMiddleware',
                # 'django.middleware.csrf.CsrfViewMiddleware',
                'django.contrib.auth.middleware.AuthenticationMiddleware',
                'django.contrib.messages.middleware.MessageMiddleware',
                'django.middleware.clickjacking.XFrameOptionsMiddleware',
            ]
    

    3.1 form表单 action参数书写的形式

    • 不写默认提交地址为当前页面
    • 只写请求地址后缀(/index)
    • 写全路径

    3.2 request对象及方法

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        {% load static %}
        <script src="{% static 'bootstrap/js/jquery.js' %}"></script>
        <link rel="stylesheet" href="{% static 'bootstrap/css/bootstrap.min.css' %}">
        <script src="{% static 'bootstrap/js/bootstrap.js' %}"></script>
    </head>
    <body>
    <form action="" method="post">
        <div class="container">
            <div class="row">
                <div class="col-md-6 col-md-offset-2 ">
                    <h1 class="text-center">登录界面</h1>
                    <input type="text" class="form-control" name="username"><br>
                    <input type="password" class="form-control" name="password"><br>
                    <input type="checkbox" name="hobby" value="backbll"> 篮球
                    <input type="checkbox" name="hobby" value="xiaoball"> 小球
                    <input type="checkbox" name="hobby" value="daball"> 打球<br>
                    <input type="submit" class="btn btn-primary"><br>
                </div>
            </div>
        </div>
    </form>
    </body>
    </html>
    
    def login(request):
        # if request.method == 'GET':
        #     # 你应该针对不同的请求方式 有不同的处理逻辑
        #     # print('走了我')
        #     # 获取请求方式  结果是一个大写的字符串
        #     print(request.method,type(request.method))
        #     return render(request,'login.html')
        # elif request.method == 'POST':
        #     pass
        """由于get请求比较常见 并且业务逻辑简单 所以针对get不需要做逻辑判断 默认就是get请求"""
        if request.method == 'POST':
            # 获取前端传递过来的用户名和密码
            print(request.POST)  # post请求提交过来的数据  <QueryDict: {'username': ['admin'], 'password': ['123']}>
            # 你可以直接将request.POST当成字典即可
            username = request.POST.get('username')
            password = request.POST.get('password')
            hobby = request.POST.getlist('hobby')
            print(username,type(username))
            print(password,type(password))
            print(hobby,type(hobby))
            """
            <QueryDict: {'username': ['admin', 'tank'], 'password': ['123']}>
            tank <class 'str'>
            123 <class 'str'>
            request.POST.get('username') 默认只取列列表的最后一个元素
            如果你想将列表完整的取出 你必须用getlist()
            """
        # print(request.GET)
        # username = request.GET.get('username')
        # password = request.GET.get('password')
        # hobby = request.GET.getlist('hobby')
        # print(username, type(username))
        # print(password, type(password))
        # print(hobby, type(hobby))
    
        return render(request, 'login.html')
    
    1. 获取请求方式

      根据获取不同的请求方式,进行不同的逻辑出来,默认为GET请求··

    request.method  # GET / POST,<class 'str'>
    
    1. 获取前端提交数据

      request.POST.get("") 如果有多个数据列表比如爱好,只会获取最后一个爱好,所以他只能获取一个值,

      request.POST.getlist("") 可以获取多个值,返回一个列表

      post请求提交过来的数据 <QueryDict: {'username': ['admin'], 'password': ['123']}>

    username = request.POST.get("username")
    password = request.POST.get("password")
    

    四、django连接数据库

    1. pycharm连接数据库

    pycharm连接数据库 数据库可能会导致连接不上,是因为jdbc版本从而导致的,可以更改驱动版本,获奖数据库系统时间SYSTEM更该为 +8:00

    1. django连接数据库

      • 第一步在settings.py中配置数据库连接
      • 第二步在--init--.py中更改数据库连接的方式
      # 第一步配置文件中配置
      DATABASES = {
            'default': {
             'ENGINE': 'django.db.backends.mysql',  # 指定数据库 MySQL postgreSQL
              'NAME': 'day56',  # 到底使用哪个库
              'USER':'root',
              'PASSWORD':'root',
              'HOST':'127.0.0.1', 
              'PORT':3306,
              'CHARSET':'utf8'
         }
      }
       
      # 第二步 django默认使用的是mysqldb连接数据库  但是该模块不支持了 所以你要告诉django不要用mysqldb该用pymysql连接 你可以在项目名下面的__init__.py也可以在应用名下面的__init__.py文件中指定
      import pymysql
      pymysql.install_as_MySQLdb()
      
      1. django的orm操作

        orm对象关系映射

      数据库中的表
      对象 表单记录
      对象获取属性 记录的某个字段对应的值

      优点:能够让一个不会数据库操作的人 也能够简单快捷去使用数据库

      缺点:由于封装程度太高 可能会导致程序的执行效率偏低,有时候 结合项目需求 可能需要你手写sql语句

      注意事项:django的orm不会自动帮你创建库,库需要你自己手动创建,表会自动帮你创建 你只需要书写符合django orm语法的代码即可,去应用下所在的models.py中书写类

      1. 创建表
      # models.py
      class UserInfo(models.Model):
          # 设置id字段为userinfo表的主键  id int primary key auto_increment
          id = models.AutoField(primary_key=True)  # 在django中 你可以不指定主键字段 django orm会自动给你当前表新建一个名为id的主键字段
          # 设置username字段  username varchar(64)  CharField必须要指i定max_length参数
          username = models.CharField(max_length=32)  # 在django orm中 没有char字段  但是django 暴露给用户 可以自定义char字段
          # 设置password字段  password int
          password = models.IntegerField()
          # phone = models.BigIntegerField(default=110)  # 新增的字段 可以提前设置默认值
          # addr = models.CharField(max_length=64,null=True)  # 新增的字段 可以设置为空
          
      
      • 新增的字段,设置默认值,或指明为空

      创建表需要两条命令:

      python manage.py makemigrations  # 初始化表,会在migrations文件夹中创建0001——initila.py,创建一条记录
      

    python manage.py migrate

    
    第一步:在models.py中创建与之对应的表类,(如果没有指定id,他会自动创建一个id为主键,并且id只能用于主键,)
    
    第二步: 使用 python manage.py makemigrations 执行该命令会在migrations文件夹中产生0001\_\_initial.py文件,同时会产生一条记录,数据库中并没有创建真实的数据库,
    
    第三步: 使用python manage.py migrate. 执行该命令会真实创建用户信息表,第一次创建,Django也会创建其他的数据库
    
    <span style="color:red">注意:</span>一旦 你在models.py中修改了跟数据库相关的代码  你就必须重新开始执行上面两条命令
    
    * 如果想要修改字段,可以在创建类中进行修改<span style="color:red">慎重</span>,重新之中上面的两条命令
    
    5. 数据库的增删改查
    
       查询数据
       		get(),filter(),all() 		
    
    ``` python
    # 查询数据
    
    def login(request):
        if request.method == 'POST':
            username = request.POST.get("username")
            password = request.POST.get("password")
      
            # 1.get()  当查询条件不存在的时候 会直接报错   如果存在会直接给你返回 数据对象本身        不推荐使用
            # res = models.Userinfo.objects.get(username=username)  # select id,username,password from userinfo where username='jason'
            # print(res)
            # print(res.username)
            # print(res.password)
            # 2.filter()   当查询条件不存在的时候  不会报错而是返回一个空
            # 当条件存在的情况下 无论数据有几条返回的都是列表套对象的数据格式
            # filter可以当多个查询条件 并且是and关系
            res = models.Userinfo.objects.filter(username=username)  # select * from userinfo where username='jason' and password=123;
            # user_obj = res[0]
            # user_obj = res[0:3]
            # user_obj = res[-1]  # 你可以将filter查询出来的结果当做列表去对待 支持正数的索引取值和切片 不支持负数
            user_obj = res.first()  # 取queryset第一个元素
         print(user_obj)
     return render(request,'login.html')
    

    get用法:

    • 当查询条件不存在的时候 会直接报错 如果存在会直接给你返回 数据对象本身 (不推荐使用),

      • 多个查询条件是and关系
    • 直接返回对象本身

      filter:

      • 当查询条件不存在的时候 不会报错而是返回一个空
      • 当条件存在的情况下 无论数据有几条返回的都是列表套对象的数据格式
      • filter可以当多个查询条件 并且是and关系
      • 查询结果为列表,不推荐使用切片获取,支持正数的所有取值和切片,不支持负数
      • 返回对象列表

      注意:使用get条件查询,查不到数据就会报错,尽量使用filter查询数据

      创建数据

    # 插入数据
    def reg(request):
        if request.method == 'POST':
            username = request.POST.get("username")
            password = request.POST.get("password")
            # 直接将用户名和密码写入数据库
            user_obj = models.Userinfo.objects.create(username=username,password=password)
            # insert into userinfo(username,password) values('admin','666');
            # create方法会有一个返回值  返回值就是当前被创建的数据对象
            print(user_obj)
        return render(request,'register.html')
    
    
    # 修改数据
    def update(request):
        user_id = request.GET.get("id")
        print(user_id)
        if request.method == 'POST':
            username = request.POST.get('username')
            password = request.POST.get('password')
            models.UserInfo.objects.filter(pk=int(user_id)).update(username=username, password=password) # 会修改查询到的数据全被修改
            return redirect('/index')
    
        user_dic = models.UserInfo.objects.filter(pk=int(user_id)).first()
    
        return render(request, 'update.html', locals())
    
    """
    	1.方式1
            modeles.Userinfo.objects.filter(**kwargs).update()  # 批量更新
    		2.方式2  (不推荐使用 效率极低 会将每一个字段对应的值全部重写一遍)
            edit_obj = models.Userinfo.objects.filter(pk=edit_id).first()  # pk会自动帮你查找当前表的主键字段
            edit_obj.username = username
            edit_obj.password = password
            edit_obj.save()  
            
    """
    
    # 删除数据
    
    def delete(request):
        user_id = request.GET.get("id")
    
        models.UserInfo.objects.filter(pk=int(user_id)).delete()
    
        # rendirect重定向带数据
        # render不带数据
        return redirect('/index')
    """
     
            删除
            models.Userinfo.objects.filter(pk=delete_id).delete()
            """说真正的数据是不会被删除的 通常都是给数据设置一个是否删除的标志位"""
    
    """
    

    一张大表化成两张表一对一

    在当下的阶段,必将由程序员来主导,甚至比以往更甚。
  • 相关阅读:
    Person Re-identification 系列论文笔记(四):Re-ID done right: towards good practices for person re-identification
    [转]embedding technic:从SNE到t-SNE再到LargeVis
    Person Re-identification 系列论文笔记(三):Improving Person Re-identification by Attribute and Identity Learning
    Person Re-identification 系列论文笔记(二):A Discriminatively Learned CNN Embedding for Person Re-identification
    Person Re-identification 系列论文笔记(一):Scalable Person Re-identification: A Benchmark
    对The Curse of Dimensionality(维度灾难)的理解
    [转]The Curse of Dimensionality(维数灾难)
    [MS Office Word] 小型大写字母
    [MS Office Word] 英文字母大小写快捷键
    [MATLAB] asv文件
  • 原文地址:https://www.cnblogs.com/randysun/p/11746801.html
Copyright © 2020-2023  润新知