django 记录一 基本配置、模板和单表查询

路由系统


urls.py配置

# url(正在表达式, 视图参数, 可选参数)

from django.conf.urls import url
from django.contrib import admin
from app_01 import views

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^index/', views.index),   
]

# 无分名组
url(r'^index/(\d+)/(\d+)/',views.index)    # def index(request,n,m)  位置参数

# 有分名组
url(r'^index/(?P\d+)/(?P\d+)/',views.index)    # def index(request,year,month) 关键字参数,参数顺序不要求

# 视图函数参数默认值
url(r'^index/$',views.index),
url(r'^index/(?P\d+)/,views.index)    # def index(request,num='1'):
# 分发路由include

# 项目的urls.py
from django.conf.urls import url,include
from django.contrib import admin
from app01 import views

urlpatterns = [
    # url(r'^admin/', admin.site.urls),
    url(r'^$', views.base),    # 首页
    url(r'^app01/', include('app01.urls')),    # app01的分发路由
    url(r'^app02/', include('app02.urls')),    # app02的分发路由
    ]

# app01的urls.py    自己创建
from django.conf.urls import url
from django.contrib import admin
from app01 import views

urlpatterns = [
    # url(r'^admin/', admin.site.urls),
    url(r'^$', views.app01base),
    url(r'^index/', views.index),
    ]

# app02的urls.py
from django.conf.urls import url
from django.contrib import admin
from app01 import views

urlpatterns = [
    # url(r'^admin/', admin.site.urls),
    url(r'^$', views.app02base),
    url(r'^index/', views.index),
    ]

url别名反向解析

  • 将url添加别名,并且根据别名能够正确调取url地址
  • 灵活配置,无论前面怎么变,都能根据别名正确找到想要的地址
# urls.py

urlpatterns = [
    url(r'^home', views.home, name='home'),
    url(r'^index/(\d*)', views.index, name='index'),
]
# html

{% url 'home' %}
{% url 'index' num %}
# views.py

from django.urls import reverse

def home(request):
    # return redirect(reverse("index", args=("2018", )))
    return redirect(reverse('别名'))

 

视图views


请求相关(request——HttpRequest对象)

request.method        # 判断请求方式
request.body          # 获取post请求提交过来的原始数据 byte类型
request.POST          # 获取post请求提交的数据
request.GET           # 获取get请求提交的数据
request.GET.urlencode()    # name=demo&age=18
request.META          # 请求头相关信息,一个大字典
request.path          # 路径 /crm/customer_show/
request.path_info     # 路径 /crm/customer_show/
request.is_ajax()     # 判断是否为ajax请求
request.get_full_path()    # /crm/customer_show/?page=5&abc=123&bcd=345
request.GET.copy()    # 将 request.GET对象改成可修改的

响应相关

from django.shortcuts import render, HttpResponse, redirect
from django.http import JsonResponse
from django.utils.safestring import mark_safe

HttpResponse    # 回复字符串时候使用
render          # 回复一个html页面时候使用
redirect        # 重定向
JsonResponse    # 将数据转换为json形式回复页面,如果是数组需要添加参数safe=False
mark_safe       # 如果返回的是html页面代码块,如ht=""这种内容,用mark_safe返回,相当于页面{{ ht|safe }}

 

FBV和CBV


# FBV (function based view)
def home(request):
    print('home!!!')
    return render(request,'home.html')
# CBV (class based view)

from django.views import View

class LoginView(View):
    # 通过请求方法找到自己写的视图类里面对应的方法
    def get(self,request):
        return render(request,'login2.html')
    
    def post(self,request):
        username = request.POST.get('uname')
        password = request.POST.get('pwd')
        print(username,password)
            return HttpResponse('登录成功!')
       
     
# urls.py
url(r'^login2/', views.LoginView.as_view()),

CBV中dispatch做中间件

具体dispatch作用可看我的另一篇文章:django 源码部分

class LoginView(View):
    def dispatch(self, request, *args, **kwargs):
        print("请求来了")
        ret = super().dispatch(request, *args, **kwargs)
        print("我走了")
        return ret


# 请求来了
# [15/Jul/2020 11:40:11] "GET /app02/login/ HTTP/1.1" 200 443
# 我走了

FBV加装饰器

def wrapper(f):
    def inner(*args, **kwargs):
        print("请求前做的事情")
        ret = f(*args, **kwargs)
        print("请求之后做的事情")
        return ret
    return inner


@wrapper
def login(request):
    print("login")
    return HttpResponse("200")

CBV加装饰器

from django.utils.decorators import method_decorator


def wrapper(f):
    def inner(*args, **kwargs):
        print("请求前做的事情")
        ret = f(*args, **kwargs)
        print("请求之后做的事情")
        return ret
    return inner

# @method_decorator(wrapper, name='get')      # 方法二
class LoginView(View):
    @method_decorator(wrapper)                # 方法三:给所有方法加装饰器
    def dispatch(self, request, *args, **kwargs):
        print("请求来了")
        ret = super().dispatch(request, *args, **kwargs)
        print("我走了")
        return ret

    def get(self, request):
        print("get方法")
        return render(request, "login.html")

    # @method_decorator(wrapper)      # 方法一
    def post(self, request):
        usr = request.POST.get("username")
        pwd = request.POST.get("password")
        print(f'{usr}--{pwd}')
        return HttpResponse("200")

 

模板


语法:
{{ 变量 }}
{% 逻辑 %}

 深度查询(.)

# 深度查询据点符(.)在模板语言中有特殊的含义。当模版系统遇到点("."),它将以这样的顺序查询:
# 字典查询(Dictionary lookup)
# 属性或方法查询(Attribute or method lookup)
# 数字索引查询(Numeric index lookup)


# views
def index(request):
    num = 10
    name = "路飞"
    name_list = ["路飞", "娜美", "索隆"]
    name_dict = {"name": "路飞", "hobby": "吃肉"}

    class Animal:
        def __init__(self):
            self.kind = "dog"

        def eat(self):
            return "肉"
    a = Animal()
    return render(request, "index.html", {"num": num, "name": name, "name_list": name_list, "name_dic": name_dict, "a": a})
    # return render(request, "index.html", locals())        # 将所有数据都封装到一个大字典中


# html 取值

{{ num }}

# 10

{{ name }}

# 路飞

{{ name_list }}————{{ name_list.1 }}

# ['路飞', '娜美', '索隆']————娜美

{{ name_dic }}————{{ name_dic.name }}

# {'name': '路飞', 'hobby': '吃肉'}————路飞

{{ a }}--{{ a.kind }}————{{ a.eat }}

# .Animal object at 0x000001B158E8DBA8>--dog————肉

常用过滤器

{{ value|default:"nothing" }}    # 变量为空或false时给定默认值
{{ value|length }}               # 返回值的长度
{{ value|filesizeformat }}       # 将值格式化为一个 “人类可读的” 文件尺寸 (例如 '13 KB', '4.1 MB', '102 bytes', 等等)
{{ value|slice:"1:5" }}          # 切片
{{ value|date:"Y-m-d H:i:s" }}   # 时间格式化
{{ value|truncatechars:9}}       # 如果字符串大于指定长度则以...省略结尾
{{ value|truncatewords:3}}       # 截断字符串,如:路飞 娜美 索隆 罗宾 返回:路飞 娜美 索隆...
{{ value|cut:' ' }}              # 移除value中所有的与给出的变量相同的字符串
{{ value|join:'+' }}             # 使用字符串连接,跟python的join一样
{{ value|safe }}                 # 表示字符安全,如果value为script如果不写safe会被当成字符串处理

for循环标签

# 普通循环
{% for i in 数据 %}
    {{ i }}
{% endfor %}

# 字典循环
{% for k,v in 字典.items %}
    {{ k }}——{{ v }}
{{ endfor }}

# empty
    {% for foo in 数据 %}
  • {{ foo }}
  • {% empty %}
  • 查询的内容啥也没有
  • {% endfor %}

for循环其他方法

forloop.counter            # 当前循环的索引值(从1开始),forloop是循环器,通过点来使用功能
forloop.counter0           # 当前循环的索引值(从0开始)
forloop.revcounter         # 当前循环的倒序索引值(从1开始)
forloop.revcounter0        # 当前循环的倒序索引值(从0开始)
forloop.first              # 当前循环是不是第一次循环(布尔值)
forloop.last               # 当前循环是不是最后一次循环(布尔值)
forloop.parentloop         # 本层循环的外层循环的对象,再通过上面的几个属性来显示外层循环的计数等
forloop.parentloop.counter
# 数据源:name_list = ["路飞", "娜美", "索隆"]

{% for i in name_list %}
    {{ forloop.counter }}
    {{ i }}                    # 1 路飞 2 娜美 3 索隆
{% endfor %}       

{% for i in name_list %}
    {{ forloop.counter0 }}
    {{ i }}                    # 0 路飞 1 娜美 2 索隆
{% endfor %}      

{% for i in name_list %}
    {{ forloop.revcounter }}
    {{ i }}                    # 3 路飞 2 娜美 1 索隆   
{% endfor %} 
  
{% for i in name_list %}
    {{ forloop.revcounter0 }}
    {{ i }}                    # 2 路飞 1 娜美 0 索隆
{% endfor %}

{% for i in name_list %}
    {{ forloop.first }}
    {{ i }}                    # True 路飞 False 娜美 False 索隆
{% endfor %}

# 数据源:name_hobby = [["路飞", "吃饭", "睡觉"], ["布鲁克", "牛奶", "内裤"]]
    {% for foo in name_hobby %}
  • {% for fo in foo %} {{ forloop.parentloop.counter }} {# {{ forloop.counter }}#} {{ fo }} # 1 路飞 1 吃饭 1 睡觉 {% endfor %} # 2 布鲁克 2 牛奶 2 内裤
  • {% endfor %}

if标签

{% if num > 100 or num < 0 %}
    

无效

{% elif num > 80 and num < 100 %}

优秀

{% else %}

凑活吧

{% endif %} if语句支持 and 、or、==、>、<、!=、<=、>=、in、not in、is、is not判断,注意条件两边都有空格。

with标签

# 给一个复杂的变量起别名
{% with total=business.employees.count %}
    {{ total }} 
{% endwith %}

csrf_token

用于跨站请求伪造保护,post提交数据时候使用。
在
表单里面加上{% csrf_token %},会在提交数据时候加上一个input标签,里面存放一个随机的value字符串,django会校验这个value随机字符串,如果和django存放的一致,则通过验证。防止反爬虫和恶意攻击 装饰器 在视图函数上面加 @csrf_exempt 允许跨站请求 @csrf_protect 不允许跨站请求

 

模板继承


django 记录一 基本配置、模板和单表查询_第1张图片

  • 当我们其他页面大体布局和一些内容和上面的html很相似时候,就可以创建一个母版(base.html)页面,其他页面继承模板,并且在自己相应需要修改的地方引入(extend)自己文件。
  • 在模板中创建多个钩子,最少得有css、js、页面的钩子
# base.html 母版文件



    
    {% block title %} My base html {% endblock title %}



    

    
{% block content %}{% endblock %}
{% extends "base.html" %}

# 子版继承模板,并在相应钩子地方写自己的内容

{% block title %}
    xxx
{% endblock title %}

{% block sidebar %}
    yyy
{% endblock sidebar %}

{% block content %}
    zzz
{% endblock %}

 

组件


  • 类似模板,他是将常用的页面内容如导航条、页尾信息等组件保存到单独的文件中,文件任意位置导入即可

# nav.html 导航条


    
    Title
    



xx dd



    
    Title


{% include 'nav.html' %}

xxxxxxxxxx

 

自定义标签和过滤器


自定义过滤器

  • 在app应用的文件夹下创建templatetags文件夹,必须是这个名字
  • 在templatetags创建任意名字的py文件
  • 带参数的过滤器最多只能有两个参数
  • 可以放在if  for等语句后
# app01/templatetags/my_filter.py
from django import template

register = template.Library()   # register的名字是固定的,不可改变


@register.filter
def filter_ride(v1, v2):    # 带参数过滤器,参数最多只能有2个
    return v1*v2


@register.filter
def filter_add_str(v1):     # 不带参数的过滤器
    s = v1 + '添加点信息'
    return s


# html
{% load my_filter %}        # 加载过滤器文件
{{ name|filter_add_str }}   # 路飞 娜美 索隆 罗宾添加点信息
{{ num|filter_ride:5 }}     # 50

自定义标签

  • 在app应用的文件夹下创建templatetags文件夹,必须是这个名字
  • 在templatetags创建任意名字的py文件
  • 不能用在if  for等语句后
# app01/templatetags/my_tags.py
from django import template

register = template.Library()   # register的名字是固定的,不可改变


@register.simple_tag
def tag_ride(v1, v2, v3, v4):    # 可传多个参数
    n = v1*v2*v3*v4
    return n


# html
{% load my_tags %}

{% tag_ride num 5 6 7  %}

inclusion_tag

  • 多用于返回html代码片段
  • 也是在templatetags文件下创建
  • 创建一个html代码片段,py文件做逻辑插入数据等,其他页面在调用py
# result.html



    
    片段


    {% for choice in data %}
  • {{ choice }}
  • {% endfor %}
# app01\templatetags\my_inclusion.py from django import template register = template.Library() @register.inclusion_tag('result.html') # 将result.html里面的内容用下面函数的返回值渲染,然后作为一个组件一样,加载到使用这个函数的html文件里面 def show_results(n): # 参数可以传多个进来 n = 1 if n < 1 else int(n) data = ["第{}项".format(i) for i in range(1, n+1)] return {"data": data} # 这里可以穿多个值,和render的感觉是一样的{'data1':data1,'data2':data2....} # index.html 在需要的地方插入 {% load my_inclusion %} {% show_results 10 %}

 

静态文件配置


  • 像css,js,img等不需要修改的文件,我们最好单独放一个静态文件夹中
  • 在setting中进行静态文件配置,否则django找不到
STATIC_URL = '/static/' #别名

STATICFILES_DIRS = [
    os.path.join(BASE_DIR,'static_files'), # 第二个参数就是项目中你存放静态文件的文件夹名称
]
{% load static %}    # 声明在html最上面





# 获取静态文件名称 get_static_prefix = /static/   as STATIC_PREFIX = 起个别名,后面方便引用 
{% get_static_prefix as STATIC_PREFIX %}

Hi!
Hello!

 

你可能感兴趣的:(web框架,#,django框架)