zoukankan      html  css  js  c++  java
  • day19_雷神_django第二天

    django_day02

    Django的路由系统

    URL配置(URLconf)就像Django所支撑网站的目录。它的本质是URL与要为该URL调用的视图函数之间的映射表。

    1、URLconf配置

    基本格式:

    from django.conf.urls import url
    
    urlpatterns = [
         url(正则表达式, views视图,参数,别名),
    ]
    

    注意:

    Django 2.0版本中的路由系统是下面的写法(官方文档):

    from django.urls import path,re_path
    
    urlpatterns = [
        path('articles/2003/', views.special_case_2003),
        path('articles/<int:year>/', views.year_archive),
        path('articles/<int:year>/<int:month>/', views.month_archive),
        path('articles/<int:year>/<int:month>/<slug:slug>/', views.article_detail),
    ]
    

    2、正则表达式详解

    基本配置

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

    注意事项

    • urlpatterns中的元素按照书写顺序从上往下逐一匹配正则表达式,一旦匹配成功则不再继续。
    • 若要从URL中捕获一个值,只需要在它周围放置一对圆括号(分组匹配)。
    • 不需要添加一个前导的反斜杠,因为每个URL 都有。例如,应该是^articles 而不是 ^/articles。
    • 每个正则表达式前面的'r' 是可选的但是建议加上。

    补充说明

    # 是否开启URL访问地址后面不为/跳转至带有/的路径的配置项
    APPEND_SLASH=True  默认就是True
    
    如果在settings.py中设置了 APPEND_SLASH=False,此时我们再请求 http://www.example.com/blog 时就会提示找不到页面。
    

    3、 分组命名规则

    上面的示例使用简单的正则表达式分组匹配(通过圆括号)来捕获URL中的值并以位置参数形式传递给视图。

    在更高级的用法中,可以使用分组命名匹配的正则表达式组来捕获URL中的值并以关键字参数形式传递给视图。

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

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

    这个实现与前面的示例完全相同,只有一个细微的差别:捕获的值作为关键字参数而不是位置参数传递给视图函数。

    URLconf匹配的位置

    URLconf 在请求的URL 上查找,将它当做一个普通的Python 字符串。不包括GET和POST参数以及域名。
    
    例如,http://www.example.com/myapp/ 请求中,URLconf 将查找 /myapp/ 。
    
    在http://www.example.com/myapp/?page=3 请求中,URLconf 仍将查找 /myapp/ 。
    
    URLconf 不检查请求的方法。换句话讲,所有的请求方法 —— 同一个URL的POST、GET、HEAD等等 —— 都将路由到相同的函数。
    

    捕获的参数永远都是字符串

    每个在URLconf中捕获的参数都作为一个普通的Python字符串传递给视图,无论正则表达式使用的是什么匹配方式。例如,下面这行URLconf 中:

    url(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),
    

    传递到视图函数views.year_archive() 中的year参数永远是一个字符串类型。

    视图函数中指定默认值

    # urls.py中
    from django.conf.urls import url
    
    from . import views
    
    urlpatterns = [
        url(r'^blog/$', views.page),
        url(r'^blog/page(?P<num>[0-9]+)/$', views.page),
    ]
    
    # views.py中,可以为num指定默认值
    def page(request, num="1"):
        pass
    

    在上面的例子中,两个URL模式指向相同的view - views.page - 但是第一个模式并没有从URL中捕获任何东西。

    如果第一个模式匹配上了,page()函数将使用其默认参数num=“1”,如果第二个模式匹配,page()将使用正则表达式捕获到的num值。

    include其他的URLconfs

    from django.conf.urls import include, url
    
    urlpatterns = [
       url(r'^admin/', admin.site.urls),
       url(r'^blog/', include('blog.urls')),  # 可以包含其他app的URLconfs文件
    ]
    

    4、传递额外的参数给视图函数(了解)

    URLconfs 具有一个钩子,让你传递一个Python 字典作为额外的参数传递给视图函数。

    django.conf.urls.url() 可以接收一个可选的第三个参数,它是一个字典,表示想要传递给视图函数的额外关键字参数。

    from django.conf.urls import url
    from . import views
    
    urlpatterns = [
        url(r'^blog/(?P<year>[0-9]{4})/$', views.year_archive, {'foo': 'bar'}),
    ]
    

    在这个例子中,对于/blog/2005/请求,Django 将调用views.year_archive(request, year='2005', foo='bar')。
    当传递额外参数的字典中的参数和URL中捕获值的命名关键字参数同名时,函数调用时将使用的是字典中的参数,而不是URL中捕获的参数。

    5、 命名URL和URL反向解析

    咱们简单来说就是可以给我们的URL匹配规则起个名字,一个URL匹配模式起一个名字。

    这样我们以后就不需要写死URL代码了,只需要通过名字来调用当前的URL。

    举个简单的例子:

    url(r'^home', views.home, name='home'),  # 给我的url匹配模式起名为 home
    url(r'^index/(d*)', views.index, name='index'),  # 给我的url匹配模式起名为index
    

    在模板里面可以这样引用:

    {% url 'home' %}
    

    在views函数中可以这样引用:

    from django.urls import reverse
    
    reverse("index", args=("2018", ))
    

    例子:

    from django.conf.urls import url
    
    from . import views
    
    urlpatterns = [
        # ...
        url(r'^articles/([0-9]{4})/$', views.year_archive, name='news-year-archive'),
        # ...
    ]
    

    根据这里的设计,某一年nnnn对应的归档的URL是/articles/nnnn/。

    你可以在模板的代码中使用下面的方法获得它们:

    <a href="{% url 'news-year-archive' 2012 %}">2012 Archive</a>
    
    <ul>
    {% for yearvar in year_list %}
    <li><a href="{% url 'news-year-archive' yearvar %}">{{ yearvar }} Archive</a></li>
    {% endfor %}
    </ul>
    

    在Python 代码中,这样使用:

    from django.urls import reverse
    from django.shortcuts import redirect
    
    def redirect_to_year(request):
        # ...
        year = 2006
        # ...
        return redirect(reverse('news-year-archive', args=(year,)))
    

    6、命名空间模式

    即使不同的APP使用相同的URL名称,URL的命名空间模式也可以让你唯一反转命名的URL。

    命名分组
    		url(r'^pub/edit/(?P<pk>d+)/$', views.publisher_edit,name='publisher_edit'),
    		
    		模板中使用:
    			{% url 'publisher'%}   ——》/app01/publisher_list/
    			
    			命名分组
    			{% url 'publisher_edit' publisher.id %}
    			{% url 'publisher_edit' pk=publisher.id %}
    			
    		视图中使用:
    			from django.urls import reverse
    			reverse('publisher')
    			
    			命名分组
    			reverse('publisher_edit',args=(2,))
    			reverse('publisher_edit',kwargs={'pk':5})
    			
    			
    		指定namespace='app01'  
    			反向解析的时候  给name前面加上namespace   ——》     namespace:name  
    

    Django的View(视图)

    一个视图函数(类),简称视图,是一个简单的Python 函数(类),它接受Web请求并且返回Web响应。

    1、一个简单的视图

    Django使用请求和响应对象来通过系统传递状态。

    当浏览器向服务端请求一个页面时,Django创建一个HttpRequest对象,该对象包含关于请求的元数据。然后,Django加载相应的视图,将这个HttpRequest对象作为第一个参数传递给视图函数。

    每个视图负责返回一个HttpResponse对象。

    2、 CBV和FBV

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

    FBV版本

    # 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")
    

    CBV版本

    # CBV版添加班级
    
    from django.views import View
    
    
    class AddClass(View):
    
        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/")
    
    使用CBV时,urls.py中也做对应的修改:
    
    url(r'^add_class/$', views.AddClass.as_view()),
    

    3、装饰器的使用

    FBV: 正常使用 给函数上加装饰器

    def wrapper(func):
    def inner(*args, **kwargs):
        start_time = time.time()
        ret = func(*args, **kwargs)
        end_time = time.time()
        print("used:", end_time-start_time)
        return ret
    return inner
    
    
    # FBV版添加班级
    @wrapper
    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")
    

    使用装饰器装饰CBV

    # 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/")
    

    装饰器的使用:

    	FBV: 正常使用 给函数上加装饰器
    	CBV:
    		from django.utils.decorators import method_decorator
    		
    		1. 加在方法上
    		    @method_decorator(timer)
    			def get(self, request):
    			
    		2. 加在dispatch方法上
    			@method_decorator(timer)
    			def dispatch(self, request, *args, **kwargs):
    			
    		3. 加在类上
    			@method_decorator(timer,name='post')
    			@method_decorator(timer,name='get')
    			class AddPublisher(View):
    

    CBV的流程

    1. AddPublisher.as_view()  ——》 view函数
    2. 请求到来的时候 执行view函数
    	1. AddPublisher实例化 对象  ——》 self 
    	2. self.request = request
    	3. 执行self.dispatch(request, *args, **kwargs)
    		1. 通过反射 获取到 get  post 方法  ——>handler
    	
    		2. handler()  ——》  获得HttpResponse对象
    
    1. 直接用装饰器
    				(<app01.views.AddPublisher object at 0x0000023DE99E57B8>, <WSGIRequest: GET '/app01/pub/add/'>)
    				<function AddPublisher.get at 0x0000023DE992ED08>	
    
    1. 使用method_decorator
    				(<WSGIRequest: GET '/app01/pub/add/'>,)
    				<function method_decorator.<locals>._dec.<locals>._wrapper.<locals>.bound_func at 0x0000023372154EA0>
    

    4、Request对象

    请求相关的常用值

    • path_info 返回用户访问url,不包括域名
    • method 请求中使用的HTTP方法的字符串表示,全大写表示。
    • GET 包含所有HTTP GET参数的类字典对象,?号后边的参数
    • POST 包含所有HTTP POST参数的类字典对象
    • body 请求体,byte类型 request.POST的数据就是从body里面提取到的

    属性

    属性:
      django将请求报文中的请求行、头部信息、内容主体封装成 HttpRequest 类中的属性。
       除了特殊说明的之外,其他均为只读的。
    
    
    0.HttpRequest.scheme
       表示请求方案的字符串(通常为http或https)
    
    1.HttpRequest.body
    
      一个字符串,代表请求报文的主体。在处理非 HTTP 形式的报文时非常有用,例如:二进制图片、XML,Json等。
    
      但是,如果要处理表单数据的时候,推荐还是使用 HttpRequest.POST 。
    
      另外,我们还可以用 python 的类文件方法去操作它,详情参考 HttpRequest.read() 。
    
     
    
    2.HttpRequest.path
    
      一个字符串,表示请求的路径组件(不含域名)。
    
      例如:"/music/bands/the_beatles/"
    
    
    
    3.HttpRequest.method
    
      一个字符串,表示请求使用的HTTP 方法。必须使用大写。
    
      例如:"GET"、"POST"
    
     
    
    4.HttpRequest.encoding
    
      一个字符串,表示提交的数据的编码方式(如果为 None 则表示使用 DEFAULT_CHARSET 的设置,默认为 'utf-8')。
       这个属性是可写的,你可以修改它来修改访问表单数据使用的编码。
       接下来对属性的任何访问(例如从 GET 或 POST 中读取数据)将使用新的 encoding 值。
       如果你知道表单数据的编码不是 DEFAULT_CHARSET ,则使用它。
    
     
    
    5.HttpRequest.GET 
    
      一个类似于字典的对象,包含 HTTP GET 的所有参数。详情请参考 QueryDict 对象。
    
     
    
    6.HttpRequest.POST
    
      一个类似于字典的对象,如果请求中包含表单数据,则将这些数据封装成 QueryDict 对象。
    
      POST 请求可以带有空的 POST 字典 —— 如果通过 HTTP POST 方法发送一个表单,但是表单中没有任何的数据,QueryDict 对象依然会被创建。
       因此,不应该使用 if request.POST  来检查使用的是否是POST 方法;应该使用 if request.method == "POST" 
    
      另外:如果使用 POST 上传文件的话,文件信息将包含在 FILES 属性中。
    
     7.HttpRequest.COOKIES
    
      一个标准的Python 字典,包含所有的cookie。键和值都为字符串。
    
     
    
    8.HttpRequest.FILES
    
      一个类似于字典的对象,包含所有的上传文件信息。
       FILES 中的每个键为<input type="file" name="" /> 中的name,值则为对应的数据。
    
      注意,FILES 只有在请求的方法为POST 且提交的<form> 带有enctype="multipart/form-data" 的情况下才会
       包含数据。否则,FILES 将为一个空的类似于字典的对象。
    
     
    
    9.HttpRequest.META
    
       一个标准的Python 字典,包含所有的HTTP 首部。具体的头部信息取决于客户端和服务器,下面是一些示例:
    
        CONTENT_LENGTH —— 请求的正文的长度(是一个字符串)。
        CONTENT_TYPE —— 请求的正文的MIME 类型。
        HTTP_ACCEPT —— 响应可接收的Content-Type。
        HTTP_ACCEPT_ENCODING —— 响应可接收的编码。
        HTTP_ACCEPT_LANGUAGE —— 响应可接收的语言。
        HTTP_HOST —— 客服端发送的HTTP Host 头部。
        HTTP_REFERER —— Referring 页面。
        HTTP_USER_AGENT —— 客户端的user-agent 字符串。
        QUERY_STRING —— 单个字符串形式的查询字符串(未解析过的形式)。
        REMOTE_ADDR —— 客户端的IP 地址。
        REMOTE_HOST —— 客户端的主机名。
        REMOTE_USER —— 服务器认证后的用户。
        REQUEST_METHOD —— 一个字符串,例如"GET" 或"POST"。
        SERVER_NAME —— 服务器的主机名。
        SERVER_PORT —— 服务器的端口(是一个字符串)。
       从上面可以看到,除 CONTENT_LENGTH 和 CONTENT_TYPE 之外,请求中的任何 HTTP 首部转换为 META 的键时,
        都会将所有字母大写并将连接符替换为下划线最后加上 HTTP_  前缀。
        所以,一个叫做 X-Bender 的头部将转换成 META 中的 HTTP_X_BENDER 键。
    
     
    10.HttpRequest.user
    
      一个 AUTH_USER_MODEL 类型的对象,表示当前登录的用户。
    
      如果用户当前没有登录,user 将设置为 django.contrib.auth.models.AnonymousUser 的一个实例。你可以通过 is_authenticated() 区分它们。
    
        例如:
    
        if request.user.is_authenticated():
            # Do something for logged-in users.
        else:
            # Do something for anonymous users.
         
    
           user 只有当Django 启用 AuthenticationMiddleware 中间件时才可用。
    
         -------------------------------------------------------------------------------------
    
        匿名用户
        class models.AnonymousUser
    
        django.contrib.auth.models.AnonymousUser 类实现了django.contrib.auth.models.User 接口,但具有下面几个不同点:
    
        id 永远为None。
        username 永远为空字符串。
        get_username() 永远返回空字符串。
        is_staff 和 is_superuser 永远为False。
        is_active 永远为 False。
        groups 和 user_permissions 永远为空。
        is_anonymous() 返回True 而不是False。
        is_authenticated() 返回False 而不是True。
        set_password()、check_password()、save() 和delete() 引发 NotImplementedError。
        New in Django 1.8:
        新增 AnonymousUser.get_username() 以更好地模拟 django.contrib.auth.models.User。
    
     
    
    11.HttpRequest.session
    
       一个既可读又可写的类似于字典的对象,表示当前的会话。只有当Django 启用会话的支持时才可用。
        完整的细节参见会话的文档。
    

    上传文件示例

    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")
    
    页面:
    
    <body>
    <form action="" method="post" enctype="multipart/form-data">
        {% csrf_token %}
        <input type="file" name="file">
        <button type="submit">上传</button>
    </form>
    </body>
    

    请求相关方法

    1.HttpRequest.get_host()
    
      根据从HTTP_X_FORWARDED_HOST(如果打开 USE_X_FORWARDED_HOST,默认为False)和 HTTP_HOST 头部信息返回请求的原始主机。
       如果这两个头部没有提供相应的值,则使用SERVER_NAME 和SERVER_PORT,在PEP 3333 中有详细描述。
    
      USE_X_FORWARDED_HOST:一个布尔值,用于指定是否优先使用 X-Forwarded-Host 首部,仅在代理设置了该首部的情况下,才可以被使用。
    
      例如:"127.0.0.1:8000"
    
      注意:当主机位于多个代理后面时,get_host() 方法将会失败。除非使用中间件重写代理的首部。
    
     
    
    2.HttpRequest.get_full_path()
    
      返回 path,如果可以将加上查询字符串。
    
      例如:"/music/bands/the_beatles/?print=true"
    
     
    
    3.HttpRequest.get_signed_cookie(key, default=RAISE_ERROR, salt='', max_age=None)
    
      返回签名过的Cookie 对应的值,如果签名不再合法则返回django.core.signing.BadSignature。
    
      如果提供 default 参数,将不会引发异常并返回 default 的值。
    
      可选参数salt 可以用来对安全密钥强力攻击提供额外的保护。max_age 参数用于检查Cookie 对应的时间戳以确保Cookie 的时间不会超过max_age 秒。
    
            复制代码
            >>> request.get_signed_cookie('name')
            'Tony'
            >>> request.get_signed_cookie('name', salt='name-salt')
            'Tony' # 假设在设置cookie的时候使用的是相同的salt
            >>> request.get_signed_cookie('non-existing-cookie')
            ...
            KeyError: 'non-existing-cookie'    # 没有相应的键时触发异常
            >>> request.get_signed_cookie('non-existing-cookie', False)
            False
            >>> request.get_signed_cookie('cookie-that-was-tampered-with')
            ...
            BadSignature: ...    
            >>> request.get_signed_cookie('name', max_age=60)
            ...
            SignatureExpired: Signature age 1677.3839159 > 60 seconds
            >>> request.get_signed_cookie('name', False, max_age=60)
            False
            复制代码
             
    
    
    4.HttpRequest.is_secure()
    
      如果请求时是安全的,则返回True;即请求通是过 HTTPS 发起的。
    
     
    
    5.HttpRequest.is_ajax()
    
      如果请求是通过XMLHttpRequest 发起的,则返回True,方法是检查 HTTP_X_REQUESTED_WITH 相应的首部是否是字符串'XMLHttpRequest'。
    
      大部分现代的 JavaScript 库都会发送这个头部。如果你编写自己的 XMLHttpRequest 调用(在浏览器端),你必须手工设置这个值来让 is_ajax() 可以工作。
    
      如果一个响应需要根据请求是否是通过AJAX 发起的,并且你正在使用某种形式的缓存例如Django 的 cache middleware, 
       你应该使用 vary_on_headers('HTTP_X_REQUESTED_WITH') 装饰你的视图以让响应能够正确地缓存。
    

    注意:键值对的值是多个的时候,比如checkbox类型的input标签,select标签,需要用:

    request.POST.getlist("hobby")
    

    5、Response对象

    HttpResponse('字符串')
    render(request,'html文件名',{})    完整的页面
    redirect(地址)  '/zz/'   'https://v3.bootcss.com/css/#forms'    Location :'/zz/'
    

    JSON

    方法一:
    后端:
    	在试图函数中,return HttpResponse(json.dunps(data)),将字典转化为字符串。
    
    前端:
    
    	在浏览器得console里,JSON.parse('{"name":"ALEX"}'),就把字符串转换为对象了
    
    方法二:
    
    from django.http import JsonResponse
    
    return sonResponse({'foo': 'bar'}),浏览器不用parse了。
    
    方法三:(设置响应头得方式)
    def data_json(request):
        data = {'name': 'alex', 'age': 73}
        data_list = [1, 22, 34, ]
        ret = HttpResponse(json.dumps(data))
        ret['Content-Type'] = 'application/json'
        # return ret  # Content-Type: text/html; charset=utf-8
        return JsonResponse(data_list, safe=False)  # Content-Type: application/json
    

    注意:

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

    response = JsonResponse([1, 2, 3], safe=False)
    

    Django模板系统

    1、常用语法

    Django模板中只需要记两种特殊符号:
    
    {{  }}和 {% %}
    
    {{ }}表示变量,在模板渲染的时候替换成值,{% %}表示逻辑相关的操作。
    

    变量

    view中代码:

    def template_test(request):
        l = [11, 22, 33]
        d = {"name": "alex"}
    
        class Person(object):
            def __init__(self, name, age):
                self.name = name
                self.age = age
    
            def dream(self):
                return "{} is dream...".format(self.name)
    
        Alex = Person(name="Alex", age=34)
        Egon = Person(name="Egon", age=9000)
        Eva_J = Person(name="Eva_J", age=18)
    
        person_list = [Alex, Egon, Eva_J]
        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 }}
    

    注意:

    注:当模板系统遇到一个(.)时,会按照如下的顺序去查询:
    
    在字典中查询
    属性或者方法
    数字索引
    

    Filters

    翻译为过滤器,用来修改变量的显示结果。

    语法: {{ value|filter_name:参数 }}

    '|'左右没有空格没有空格没有空格

    default  

    {{ value|default:"nothing"}}
    如果value值没传的话就显示nothing
    

    filesizeformat

    将值格式化为一个 “人类可读的” 文件尺寸 (例如 '13 KB', '4.1 MB', '102 bytes', 等等)。例如:

    {{ value|filesizeformat }}
    

    add

    {{ value|add:"2" }}
    value是数字4,则输出结果为6。
    
    {{ first|add:second }}
    如果first是 [1,.2,3] ,second是 [4,5,6] ,那输出结果是 [1,2,3,4,5,6] 。
    

    lower

    小写
    
    {{ value|lower }}
    

    length

    {{ value|length }}
    
    返回value的长度,如 value=['a', 'b', 'c', 'd']的话,就显示4.
    

    date

    日期格式化
    
    {{ value|date:"Y-m-d H:i:s"}}
    
    全局的配置:
    	在settings里面写:
    	DATATIME_FORMAT = 'Y-m-d H:i:s'
    	USE_LION = False
    

    safe

    为了在Django中关闭HTML的自动转义有两种方式,如果是一个单独的变量我们可以通过过滤器“|safe”的方式告诉Django这段代码是安全的不必转义。

    比如:
    
    value = "<a href='#'>点我</a>"
    
    {{ value|safe}}
    

    2、 tag 标签

    for循环可用的一些参数:

    Variable	Description
    forloop.counter	当前循环的索引值(从1开始)
    forloop.counter0	当前循环的索引值(从0开始)
    forloop.revcounter	当前循环的倒序索引值(从1开始)
    forloop.revcounter0	当前循环的倒序索引值(从0开始)
    forloop.first	当前循环是不是第一次循环(布尔值)
    forloop.last	当前循环是不是最后一次循环(布尔值)
    forloop.parentloop	本层循环的外层循环  需要引用外出循环的一些参数时候
    

    for ... empty

    <ul>
    {% for user in user_list %}
        <li>{{ user.name }}</li>
    {% empty %}
        <li>空空如也</li>
    {% endfor %}
    </ul>
    
    示例:
    	{% empty %}
    	<tr><td colspan='4' style='text-aline:center'>没有数据</td></tr>
    

    csrf_token

    这个标签用于跨站请求伪造保护。
    
    在页面的form表单里面写上{% csrf_token %}
    

    if,elif和else

    {% if user_list %}
      用户人数:{{ user_list|length }}
    {% elif black_list %}
      黑名单数:{{ black_list|length }}
    {% else %}
      没有用户
    {% endif %}
    
    if语句支持 and 、or、==、>、<、!=、<=、>=、in、not in、is、is not判断。
    

    注意事项:

    1. Django的模板语言不支持连续判断,即不支持以下写法:

      {% if a > b > c %}
      ...
      {% endif %}

    3、 母版

    继承母版

    在子页面中在页面最上方使用下面的语法来继承母板。
    
    {% extends 'layouts.html' %}
    

    块(block)

    通过在母板中使用{% block  xxx %}来定义"块"。
    
    在子页面中通过定义母板中的block名来对应替换母板中相应的内容。
    
    {% block page-main %}
      <p>世情薄</p>
      <p>人情恶</p>
      <p>雨送黄昏花易落</p>
    {% endblock %}
    

    组件

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

    静态文件相关

    - {% load static %}
    	
    	<link rel="stylesheet" href="{% static 'bootstrap-3.3.7/css/bootstrap.css' %}"
    	<link rel="stylesheet" href="{% static 'css/dsb.css' %}">}
    
    	<link rel="stylesheet" href="{% get_static_prefix %}bootstrap-3.3.7/css/bootstrap.css">
    	<link rel="stylesheet" href="{% get_static_prefix %}css/dsb.css">
    

    Django的Object Relational Mapping(ORM)

    常用字段

    AutoField
    
    自增的整形字段,必填参数primary_key=True,则成为数据库的主键。无该字段时,django自动创建。
    
    一个model不能有两个AutoField字段。
    
    IntegerField
    
    一个整数类型。数值的范围是 -2147483648 ~ 2147483647。
    
    CharField
    
    字符类型,必须提供max_length参数。max_length表示字符的长度。
    
    DateField
    
    日期类型,日期格式为YYYY-MM-DD,相当于Python中的datetime.date的实例。
    
    参数:
    
    auto_now:每次修改时修改为当前日期时间。
    auto_now_add:新创建对象时自动添加当前日期时间。
    auto_now和auto_now_add和default参数是互斥的,不能同时设置。
    
    DatetimeField
    
    日期时间字段,格式为YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ],相当于Python中的datetime.datetime的实例。
    

    字段类型

    	AutoField(Field)
            - int自增列,必须填入参数 primary_key=True
    
        BigAutoField(AutoField)
            - bigint自增列,必须填入参数 primary_key=True
    
            注:当model中如果没有自增列,则自动会创建一个列名为id的列
            from django.db import models
    
            class UserInfo(models.Model):
                # 自动创建一个列名为id的且为自增的整数列
                username = models.CharField(max_length=32)
    
            class Group(models.Model):
                # 自定义自增列
                nid = models.AutoField(primary_key=True)
                name = models.CharField(max_length=32)
    
        SmallIntegerField(IntegerField):
            - 小整数 -32768 ~ 32767
    
        PositiveSmallIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
            - 正小整数 0 ~ 32767
    
        IntegerField(Field)
            - 整数列(有符号的) -2147483648 ~ 2147483647
    
        PositiveIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
            - 正整数 0 ~ 2147483647
    
        BigIntegerField(IntegerField):
            - 长整型(有符号的) -9223372036854775808 ~ 9223372036854775807
    
        BooleanField(Field)
            - 布尔值类型
    
        NullBooleanField(Field):
            - 可以为空的布尔值
    
        CharField(Field)
            - 字符类型
            - 必须提供max_length参数, max_length表示字符长度
    
        TextField(Field)
            - 文本类型
    
        EmailField(CharField):
            - 字符串类型,Django Admin以及ModelForm中提供验证机制
    
        IPAddressField(Field)
            - 字符串类型,Django Admin以及ModelForm中提供验证 IPV4 机制
    
        GenericIPAddressField(Field)
            - 字符串类型,Django Admin以及ModelForm中提供验证 Ipv4和Ipv6
            - 参数:
                protocol,用于指定Ipv4或Ipv6, 'both',"ipv4","ipv6"
                unpack_ipv4, 如果指定为True,则输入::ffff:192.0.2.1时候,可解析为192.0.2.1,开启此功能,需要protocol="both"
    
        URLField(CharField)
            - 字符串类型,Django Admin以及ModelForm中提供验证 URL
    
        SlugField(CharField)
            - 字符串类型,Django Admin以及ModelForm中提供验证支持 字母、数字、下划线、连接符(减号)
    
        CommaSeparatedIntegerField(CharField)
            - 字符串类型,格式必须为逗号分割的数字
    
        UUIDField(Field)
            - 字符串类型,Django Admin以及ModelForm中提供对UUID格式的验证
    
        FilePathField(Field)
            - 字符串,Django Admin以及ModelForm中提供读取文件夹下文件的功能
            - 参数:
                    path,                      文件夹路径
                    match=None,                正则匹配
                    recursive=False,           递归下面的文件夹
                    allow_files=True,          允许文件
                    allow_folders=False,       允许文件夹
    
        FileField(Field)
            - 字符串,路径保存在数据库,文件上传到指定目录
            - 参数:
                upload_to = ""      上传文件的保存路径
                storage = None      存储组件,默认django.core.files.storage.FileSystemStorage
    
        ImageField(FileField)
            - 字符串,路径保存在数据库,文件上传到指定目录
            - 参数:
                upload_to = ""      上传文件的保存路径
                storage = None      存储组件,默认django.core.files.storage.FileSystemStorage
                width_field=None,   上传图片的高度保存的数据库字段名(字符串)
                height_field=None   上传图片的宽度保存的数据库字段名(字符串)
    
        DateTimeField(DateField)
            - 日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ]
    
        DateField(DateTimeCheckMixin, Field)
            - 日期格式      YYYY-MM-DD
    
        TimeField(DateTimeCheckMixin, Field)
            - 时间格式      HH:MM[:ss[.uuuuuu]]
    
        DurationField(Field)
            - 长整数,时间间隔,数据库中按照bigint存储,ORM中获取的值为datetime.timedelta类型
    
        FloatField(Field)
            - 浮点型
    
        DecimalField(Field)
            - 10进制小数
            - 参数:
                max_digits,小数总长度
                decimal_places,小数位长度
    
        BinaryField(Field)
            - 二进制类型
    

    字段参数

    null                数据库中字段是否可以为空
    db_column           数据库中字段的列名
    default             数据库中字段的默认值
    primary_key         数据库中字段是否为主键
    db_index            数据库中字段是否可以建立索引
    unique              数据库中字段是否可以建立唯一索引
    

    Model Meta参数

    class UserInfo(models.Model):
        nid = models.AutoField(primary_key=True)
        username = models.CharField(max_length=32)
     
        class Meta:
            # 数据库中生成的表名称 默认 app名称 + 下划线 + 类名
            db_table = "table_name"
     
            # 联合索引 
            index_together = [
                ("pub_date", "deadline"),   # 应为两个存在的字段
            ]
     
            # 联合唯一索引
            unique_together = (("driver", "restaurant"),)   # 应为两个存在的字段
    

    ORM操作必会13条

    import os
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings")
    import django
    django.setup()
    
    from app01 import models
    # 获取对象
    ret = models.User.objects.get(id=1)
    # 获取所所有  ——》 对象列表
    ret = models.User.objects.all()
    
    # 获取所有满足条件的对象   ——》对象列表
    ret = models.User.objects.filter()
    
    # 获取所有不满足条件的对象   ——》对象列表
    ret = models.User.objects.exclude(id=1)
    
    # values  ——》对象列表   {}
    # 不写参数  拿所有字段name 和 value
    # 写参数  拿指定字段name 和 value
    ret = models.User.objects.all().values('name','id')
    
    # values_list  ——》对象列表   ()
    # 不写参数  拿所有字段value
    # 写参数  拿指定字段value
    ret = models.User.objects.all().values_list('name','id')
    
    ret = models.User.objects.all().order_by('age','-id')
    
    ret = models.User.objects.all().order_by('id').reverse()
    
    # distinct() 去重
    
    ret = models.User.objects.all().count()
    
    ret = models.User.objects.filter(id=100).exists()
    print(ret)
    
    
    """
    返回对象列表的方法
    1. all()
    2. filter()
    3. exclude()
    4. order_by()
    5. reverse()
    6. values() {}
    7. values_list()  ()
    8. distinct()
    
    返回对象的
    1. get()
    2. first()
    3. last()
    
    返回布尔值
    1. exists()
    
    返回数字的
    1. count()
    
    """
    

    单表的双下划线查询

    import os
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings")
    import django
    django.setup()
    
    from app01 import models
    
    ret = models.User.objects.filter(id__gt=1)  # greater than
    ret = models.User.objects.filter(id__gte=1)  # greater than equal
    ret = models.User.objects.filter(id__lt=5)  # less than
    ret = models.User.objects.filter(id__lte=3)  # less than equal
    
    
    ret = models.User.objects.filter(id__in=[1,3,5])
    ret = models.User.objects.filter(id__range=[1,3])
    
    
    ret = models.User.objects.filter(name__contains='e')
    # ret = models.User.objects.filter(name__icontains='e')
    ret = models.User.objects.filter(name__startswith='h')
    
    ret = models.User.objects.filter(birth__year='2018')
    ret = models.User.objects.filter(birth__month='10')
    ret = models.User.objects.filter(birth__day='13')
    
    print(ret)
    

    外键的使用及查询

    正向查找

    对象查找(跨表)

    语法:
    
    对象.关联字段.字段 
    
    示例:
    
    book_obj = models.Book.objects.first()  # 第一本书对象
    print(book_obj.publisher)  # 得到这本书关联的出版社对象
    print(book_obj.publisher.name)  # 得到出版社对象的名称
    

    字段查找(跨表)
    语法:

    关联字段__字段
    
    示例:
    
    print(models.Book.objects.values_list("publisher__name"))
    回到顶部
    

    反向操作

    对象查找

    语法:
    
    obj.表名_set
    
    示例:
    
    publisher_obj = models.Publisher.objects.first()  # 找到第一个出版社对象
    books = publisher_obj.book_set.all()  # 找到第一个出版社出版的所有书
    titles = books.values_list("title")  # 找到第一个出版社出版的所有书的书名
    

    字段查找

    语法:
    
    表名__字段
    
    示例:
    
    titles = models.Publisher.objects.values_list("book__title")
    

    示例:

    import os
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings")
    import django
    django.setup()
    
    from app01 import models
    obj=models.Book.objects.get(id=1)
    
    print(obj.publisher)
    
    ret = models.Book.objects.filter(publisher__name='沙河出版社')
    # print(ret)
    
    
    pub_obj = models.Publisher.objects.get(id=14)
    
    print(pub_obj.book_set.all())
    
    print(models.Publisher.objects.filter(book__title='九阳真经'))
    My name is 侯冰雷 ~~欢迎转载 ~~欢迎关注 ~~欢迎留言
  • 相关阅读:
    神奇的python系列10:函数(三)
    神奇的python系列9:函数(二)
    神奇的python系列8:函数(一)
    神奇的python系列7:文件操作
    神奇的python系列6:python基础数据类型补充
    神奇的python系列5:python基础数据类型三(字典)
    神奇的python系列4:python基础数据类型二(列表)
    神奇的python系列3:python基础数据类型一
    神奇的python系列2:python基础一
    Token机制,session机制
  • 原文地址:https://www.cnblogs.com/houbinglei/p/9815051.html
Copyright © 2011-2022 走看看