zoukankan      html  css  js  c++  java
  • 17-1 djanjo进阶-路由,视图,模板

    一 路由系统进阶(urls.py)

     动态路由

    urls.py中通过正则表达式的分组匹配,捕获用户访问的url中的值,传递给视图函数
    1 分组匹配(通过圆括号):
    相当于给视图函数传递 位置参数

    例子:

     1 from django.conf.urls import url
     2 
     3 from . import views
     4 
     5 urlpatterns = [
     6     url(r'^articles/2003/$', views.special_case_2003),
     7     url(r'^articles/([0-9]{4})/$', views.year_archive),
     8     url(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive),
     9     url(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.article_detail),
    10 ]

    2 分组命名匹配:
    相当于给视图函数传递 关键字参数

    在Python的正则表达式中,分组命名正则表达式组的语法是(?P<name>pattern),其中name是组的名称,pattern是要匹配的模式。

    例子:

     1 from django.conf.urls import url
     2 
     3 from . import views
     4 
     5 urlpatterns = [
     6     url(r'^articles/2003/$', views.special_case_2003),
     7     url(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),
     8     url(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$', views.month_archive),
     9     url(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<day>[0-9]{2})/$', views.article_detail),
    10 ]

    3 name

    防止将url硬编码到我们的业务逻辑代码中,给url起别名
    通过别名,反向找到 url

    配置:

    在views.py中:
    from django.urls import reverse
    具体的url = reverse('url别名')

    例子:

    urls.py里面配置:

    url(r'^publisher_list/$', views.publisher_list, name="alex")

    vivews.py引用:

    # def edit_publisher(request, edit_id):
    #     print(reverse('alex'))
    #     print("=" * 120)
    #     if request.method == "POST":
    #         new_name = request.POST.get("name888")
    #         # 去数据库修改出版社名字
    #         obj = models.Publisher.objects.get(id=edit_id)
    #         obj.name = new_name
    #         obj.save()
    #         return redirect(reverse('alex')) #返回一个url
    #     print(edit_id)
    #     publisher_obj = models.Publisher.objects.get(id=edit_id)
    #     return render(request, "edit_publisher.html", {"obj": publisher_obj})

    4 传参数的两种写法(一不小心就被坑了)

    例子一:url传参

    1 urls.py配置:

     url(r'^edit_publisher/$', views.edit_publisher),

    2 views.py 

     3 def edit_publisher(request):
        if request.method=="POST": 4 #获取用户更改的id 5 edit_id=request.POST.get("id")#从浏览器传的参数获取的id 6 new_name=request.POST.get("name")#从form表单获取的名字 7 #去数据库找到这条记录 8 obj=models.Publisher.objects.get(id=edit_id) 9 obj.name=new_name 10 obj.save() 11 return redirect("/publisher_list/") 12 else: 13 edit_id = request.GET.get("id") 14 publisher_edit = models.Publisher.objects.get(id=edit_id) 15 return render(request,"edit_publisher.html",{"obj":publisher_edit})

    注意:#上面红色字体里面的的obj一定要和你相应的edit_publisher里面的value,里面的一致,比如value=obj.name 这里就一定用obj

    3 html配置:

    publisher_list.html

     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4     <meta charset="UTF-8">
     5     <title>出版社列表</title>
     6     <link rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.min.css">
     7 </head>
     8 <body>
     9 <div class="container">
    10     <div class="row">
    11         <div class="col-md-8 col-sm-offset-2">
    12             <table class="table table-bordered">
    13                 <tr>
    14                     <th>#</th>
    15                     <th>id</th>
    16                     <th>出版社名字</th>
    17                     <th>操作</th>
    18                 </tr>
    19 
    20 {#                 data这里一定要跟views里面的data一样#}
    21                 {% for publisher in data %}
    22                     <tr>
    23                     <td>{{ forloop.counter }}</td>
    24                     <td>{{ publisher.id }}</td>
    25                     <td>{{ publisher.name }}</td>
    26                     <td>
    27 {#                           这是动态传参#}
    28 {#                        <a href="/edit_publisher/{{ publisher.id }}/" class="btn btn-info">编辑</a>#}
    29 {#                        这是浏览器传参数#}
    30                         <a href="/edit_publisher/?id={{ publisher.id }}" class="btn btn-info">编辑</a>
    31                         <a href="/del_publisher" class="btn btn-info">删除</a>
    32                     </td>
    33                     </tr>
    34                 {% endfor %}
    35             </table>
    36 
    37         </div>
    38     </div>
    39 </div>
    40 
    41 </body>
    42 </html>
    View Code

    edit_publisher.html

     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4     <meta charset="UTF-8">
     5     <title>编辑</title>
     6     <link rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.min.css">
     7 </head>
     8 <body>
     9  <form class="form-horizontal" action="" method="post">
    10         <input type="text" name="id" value="{{ obj.id }}" style="display: none">
    11         <div class="form-group">
    12             <label for="inputEmail3" class="col-sm-2 control-label">出版社名称</label>
    13             <div class="col-sm-10">
    14                 <input type="text" class="form-control" name="name" value="{{ obj.name }}" id="inputEmail3"
    15                        placeholder="新名称">
    16             </div>
    17         </div>
    18 
    19         <div class="form-group">
    20             <div class="col-sm-offset-2 col-sm-10">
    21                 <button type="submit" class="btn btn-default">提交</button>
    22             </div>
    23         </div>
    24     </form>
    25 
    26 </body>
    27 </html>
    View Code

    例子二 动态传参

    1 urls配置:

     url(r'^edit_publisher/(d+)/$', views.edit_publisher),

    2 views.py配置

     1 # def edit_publisher(request,edit_id):
     2 #     if request.method=="POST":
     3 #             #获取用户更改的id
     4 #
     5 #             new_name=request.POST.get("name")#从form表单获取的名字
     6 #             #去数据库找到这条记录
     7 #             obj=models.Publisher.objects.get(id=edit_id)
     8 #             print(obj.name)
     9 #             obj.name=new_name
    10 #             obj.save()
    11 #             return redirect("/publisher_list/")
    12 #     else:
    13 #
    14 #         publisher = models.Publisher.objects.get(id=edit_id)
    15 #         return render(request,"edit_publisher.html",{"obj":publisher})

    3 html配置:

    publisher_list.html

      <a href="/edit_publisher/{{ publisher.id }}/" class="btn btn-info">编辑</a>

    edit_publisher.html不变

    二 视图函数进阶(views.py)

    1. 1-views.py
     1.基础必会三件套
      1. HttpResponse('字符串')
      2. render(request, "xx.html", {"key": value})
      3. redirect("/其它的url/")

    2. FBV(Function Base View) 基于函数的视图
      通过request.method == "POST" 去判断

    例子:

     1 # def edit_publisher(request, edit_id):
     2 #     print(reverse('alex'))
     3 #     print("=" * 120)
     4 #     if request.method == "POST":
     5 #         new_name = request.POST.get("name888")
     6 #         # 去数据库修改出版社名字
     7 #         obj = models.Publisher.objects.get(id=edit_id)
     8 #         obj.name = new_name
     9 #         obj.save()
    10 #         return redirect(reverse('alex'))
    11 #     print(edit_id)
    12 #     publisher_obj = models.Publisher.objects.get(id=edit_id)
    13 #     return render(request, "edit_publisher.html", {"obj": publisher_obj})

    3. CBV(Class Base View) 基于类的视图
      1. 必须继承views.View -->在views.py里面导入: from django import views
      2. 写一个自己的视图类
      3. 通过定义不同的方法,来处理用户不同的请求
      4. 在urls.py中注册视图的时候要写 views.类名.as_view()

    urls.py中配置:

     url(r'^edit_publisher/(?P<edit_id>d+)/$', views.EditPublisher.as_view(), name="wusir"),

    view.py配置:

    例子:

     1 class EditPublisher(views.View):
     2     def get(self, request, edit_id):
     3         publisher_obj = models.Publisher.objects.get(id=edit_id)
     4         return render(request, "edit_publisher.html", {"obj": publisher_obj})
     5 
     6     def post(self, request, edit_id):
     7         new_name = request.POST.get("name888")
     8         # 去数据库修改出版社名字
     9         obj = models.Publisher.objects.get(id=edit_id)
    10         obj.name = new_name
    11         obj.save()
    12         return redirect(reverse('alex'))

    2.1 request对象的常用属性和方法(常用的几个)

    request表示的是和用户请求相关的所有数据
    1. request.method --> 用户当前请求的请求方法
    2. request.GET --> 用户请求中url中的参数
    3. request.POST --> 用户POST请求的数据
    4. request.path_info --> 用户访问的url路径是什么

    3.1 Django上传文件

    1. 前端页面
      1. form表单一定要有action,method必须是post
      2. 一定要配置enctype="multipart/form-data
    2. 后端:

    def upload(request):
        """
        保存上传文件前,数据需要存放在某个位置。默认当上传文件小于2.5M时,django会将上传文件的全部内容读进内存。从内存读取一次,写磁盘一次。
        但当上传文件很大时,django会把上传文件写到临时文件中,然后存放到系统临时文件夹中。
        :param request: 
        :return: 
        """
        if request.method == "POST":
            # 从请求的FILES中获取上传文件的文件名,file为页面上type=files类型input的name属性值
            filename = request.FILES["file"].name
            # 在项目目录下新建一个文件
            with open(filename, "wb") as f:
                # 从上传的文件对象中一点一点读
                for chunk in request.FILES["file"].chunks():
                    # 写入本地文件
                    f.write(chunk)
            return HttpResponse("上传OK")
    
    

    4.1 JsonResponse
    专门用来返回JSON格式数据的响应对象
    from django.http import JsonResponse

    例子:

    from django.http import JsonResponse
    
    response = JsonResponse({'foo': 'bar'})
    print(response.content)
    
    b'{"foo": "bar"}'

     默认只能传递字典类型,如果要传递非字典类型需要设置一下safe关键字参数。

    例子:

    urls.py
    
    url(r'^json_test/$', views.JsonTest.as_view()),
    
    views.py
    class JsonTest(views.View):
        def get(self, request):
            res = {"code": 0, "data": "alex"}
            res2 = ["alex", "污Sir", "金老板", "小姨妈", "MJJ"]
            return JsonResponse(res2,safe=False)

    三 模板引擎进阶

    1 模板语法:

      1. 两个语法:
        1. {{ }} --> 跟变量相关的操作
        2. {% %} --> 跟逻辑相关的操作

      2. 变量相关
        1. 传字典或对象类型的数据 obj.name/obj.age
        2. 传数组类型的数据 obj.索引值

    例子:

     1 def template_test(request):
     2     l = [11, 22, 33]
     3     d = {"name": "alex"}
     4 
     5     class Person(object):
     6         def __init__(self, name, age):
     7             self.name = name
     8             self.age = age
     9 
    10         def dream(self):
    11             return "{} is dream...".format(self.name)
    12 
    13     Alex = Person(name="Alex", age=34)
    14     Egon = Person(name="Egon", age=9000)
    15     Eva_J = Person(name="Eva_J", age=18)
    16 
    17     person_list = [Alex, Egon, Eva_J]
    18     return render(request, "template_test.html", {"l": l, "d": d, "person_list": person_list})

    取值:

    {# 取l中的第一个参数 #}
    {{ l.0 }}
    {# 取字典中key的值 #}
    {{ d.name }}
    {# 取对象的name属性 #}
    {{ person_list.0.name }}
    {# .操作只能调用不带参数的方法 #}
    {{ person_list.0.dream }}

      3. 日期格式化
        <p>{{ today|date:"Y-m-d H:i:s"}}</p>
      4. 显示真正的html代码
        <p>{{ link|safe }}</p>

    例子:

    view配置:

     1 def template_test(request):
     2     data = ["金老板", "景女神", "MJJ"]
     3     # data = ""
     4     filesize = 1234567890
     5     import datetime
     6     today = datetime.datetime.today()
     7     link = "<script>for(;;){alert(123)}</script>"
     8 
     9 
    10     class Person(object):
    11         def __init__(self, name, dream):
    12             self.name = name
    13             self.dream = dream
    14 
    15         def dream(self):
    16             return "我的梦想是学好Python!"
    17     pw = Person("彭玮", "不去下一期!")
    18 
    19     return render(request, "t.html", {
    20         "data": data,
    21         "file_size": filesize,
    22         "today": today,
    23         "link": link,
    24         "person": pw
    25     })
    View Code

    html中配置:

     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4     <meta charset="UTF-8">
     5     <title>Title</title>
     6 </head>
     7 <body>
     8 
     9 
    10 {#<p>{{ data.1 }}</p>#}
    11 <p>{{ data|default:"暂无数据" }}</p>
    12 <p>{{ file_size|filesizeformat }}</p>
    13 <p>{{ today }}</p>
    14 
    15 
    16 <p>{{ link }}</p>
    17 {#<p>{{ link|safe }}</p>#}
    18 
    19 <hr>
    20 
    21 <p>
    22     {% for teacher in data %}
    23         {% if forloop.last %}
    24             {{ teacher }}
    25         {% else %}
    26             {{ teacher }},
    27         {% endif %}
    28     {% endfor %}
    29 </p>
    30 {#<p>{% if 3 > 2 > 1 %}{% endif %}</p>#}(不支持这样写)
    31 {##}
    32 {#<p>{% if 3 > 2 and 2 > 1  %}{% endif %}</p>#}
    33 
    34 <hr>
    35 
    36 {{ person.name }}
    37 {{ person.dream }}
    38 
    39 
    40 </body>
    41 </html>
    View Code

    2. 母板
      1. 为什么要用母版?
      不同的页面有大量重复的代码,我们可以把公用的部分提取出来放在单独一个文件
      2. 怎么使用?
      1.1. 在子页面 通过使用 {% extends ‘模板名’ %} --> 放在子页面的最上面
      2. 1{% block xx %}{% endblock %}

    母版例子:

     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4     <meta charset="UTF-8">
     5     <title>{{ html_title }}</title>
     6     <link rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.min.css">
     7     {% block page-css %}
     8     
     9     {% endblock %}
    10 </head>
    11 <body>
    12 {% include 'nav.html' %}
    13 <div class="container">
    14     <div class="row">
    15         <div class="col-md-8 col-md-offset-2">
    16 
    17             {% block page-main %}
    18 
    19             {% endblock %}
    20 
    21         </div>
    22     </div>
    23 </div>
    24 <script src="/static/jquery.js"></script>
    25 {% block page-js %}
    26 
    27 {% endblock %}
    28 </body>
    29 </html>
    View Code

    3. 组件

    可以将常用的页面内容如导航条,页尾信息等组件保存在单独的文件中,然后在需要使用的地方按如下语法导入即可。
      使用 {% include '组件名' %}导入

    如何继承母版例子:

     1 {% extends 'mama.html' %}
     2 
     3 {% block page-main %}
     4 <table class="table table-bordered">
     5     <thead>
     6     <tr>
     7         <th>#</th>
     8         <th>id</th>
     9         <th>出版社名称</th>
    10         <th>操作</th>
    11     </tr>
    12     </thead>
    13     <tbody>
    14     {% for publisher in publisher_list %}
    15         <tr>
    16             <td>{{ forloop.counter }}</td>
    17             <td>{{ publisher.id }}</td>
    18             <td>{{ publisher.name }}</td>
    19             <td>
    20                 <a href="/edit_publisher/{{ publisher.id }}/" class="btn btn-info">编辑</a>
    21                 <a href="/delete_publisher/" class="btn btn-danger">删除</a>
    22             </td>
    23         </tr>
    24     {% endfor %}
    25     </tbody>
    26 </table>
    27 
    28 {% endblock %}
    29 
    30 {#我这个页面才用到的一个js文件#}
    31 {% block page-js %}
    32     <script src="/static/1.js"></script>
    33 {% endblock %}
    View Code

     四 CSRF

    1. 为什么要有csrf_token?
    2. Django中如何使用?
    在render的页面上写上{% csrf_token %}
    3. 如果是form表单形式提交,必须放在form表单中
    4 如果不加csrf_token默认是不让提交的报403错误

    例子:

    urls.py配置

     1 url(r'^csrf_test/$', views.csrf_test), 

    views.py配置:

    def csrf_test(request):
        if request.method=="POST":
            print(request.POST)
            return HttpResponse("OK")
        else:
            return render(request,"csrf_test.html")

    html配置:

    <form action="" method="post">
        {% csrf_token %}
        <input type="text" name="name">
        <input type="submit" value="提交">
    </form>
  • 相关阅读:
    hbuilder中如何使用egit上传项目
    网络攻防第二周学习笔记
    sqlserver两表关联的更新
    ISAPI_rewrite中文手册
    Unity中C#单例模式使用总结
    Window Live Writer Test
    Spring Cloud 服务注册与发现(Eureka 找到了!找到了! 嘻嘻)
    Spring Cloud 服务消费与负载均衡(feign)
    Spring Cloud 服务消费与负载均衡(Rest + Ribbon )
    列表的响应式排版
  • 原文地址:https://www.cnblogs.com/huningfei/p/9465345.html
Copyright © 2011-2022 走看看