Django基础

什么是Django

在python中有很多web框架,如Django、Flask、Tornado。Django和其他web框架相比,功能更加齐全。

Django遵循MVC框架模式,即模型(M),视图(V),控制器(C)

下载Django

pip install django=2.2

创建一个django项目

使用Pycharm创建Django项目

Django基础

命令行创建

django-admin.py startproject djangoDemo

其他Django常用命令

python manage.py runserver 0.0.0.0
python manage.py startapp appname
python manage.py syncdb
python manage.py makemigrations
python manage.py migrate
python manage.py createsuperuser

Django目录结构

Django基础

启动Django

urls.py

from django.contrib import admin
from django.urls import path
from app01 import views
urlpatterns = [
    path('admin/', admin.site.urls),
    path('', views.index),
]

views.py

from django.shortcuts import render, redirect, HttpResponse


# Create your views here.
def index(request):
    return HttpResponse('hello world')

在命令行执行

python manage.py runserver 8080

Django视图

from django.shortcuts import render, redirect, HttpResponse


# FBV ----> function based view
# 请求相关的方法
def index(request):  # http相关请求封装HtppRequest对象
    print(request.method)
    print(request.path)
    print(request.path_info)
    print(request.get_full_path())  # 包含get请求参数的路径
    print(request.GET)
    print(request.POST)
    print(request.body)  # post请求过来的原始数据
    print(request.META)     # 所有与请求相关的信息
    print(request.headers)
    return render(request, 'index.html')
    # 响应相关的方法
    # HttResponse   回复字符串
    # render        回复一个html页面
    # redirect      重定向




# CBV ----> class based view
from django.views import View
# 方法装饰器
from django.utils.decorators import method_decorator

def decorator(func):
    def wrapper(request, *args, **kwargs):
        print(f'执行{request.method}方法前')
        ret = func(request, *args, **kwargs)
        print(f'执行{request.method}方法后')
        return ret

    return wrapper


# method_decorator(decorator, name='get')               # 在类上面加
class LoginView(View):
    # @method_decorator(decorator)                      # 为所有方法加装饰器
    def dispatch(self, request, *args, **kwargs):
        return super().dispatch(request, *args, **kwargs)

    @method_decorator(decorator)  			# 直接加到方法上
    def get(self, request):
        return render(request, 'login.html')

    def post(self, request):
        username = request.POST.get('username')
        password = request.POST.get('password')
        if username == 'test' and password == '123':
            return HttpResponse('ok')
        return redirect('/login/')

FBV和CBV的区别

  • FBV ---> 路由匹配直接执行view.py里面对于的函数
  • CBV ---> 在路由匹配前执行View.as_view(cls) 然后返回view函数
  • 路由匹配成功之后执行view函数,view函数再执行View.dispatch(request, *args,**kwargs)方法,
  • dispatch再通过反射执行cls中与请求对应的方法 getattr(self,request.method,lower())

Django路由

# 单一路由对应FBV
path('index1/', views.index),
# 单一路由对队友CBV
path('index2/', views.IndexView.as_view())

# 基于正则
re_path(r'^index/(d*)/$', views.index),
re_path(r'^manage/(?P<name>w*)/(?P<id>d*)/$', views.manage),

# Django自带的路由动态传参
path('^index/<int>/', views.index),
path('^manage/<str:name>/<int:id>/', views.manage),

# 添加额外的参数
path('index/<int:id>/', views.index, {'id': 123}),

# 起别名
path('home/', views.home, name='home'),

# 路由分发
path('web/',include('web.urls')),

Django模板

过滤器

内置过滤器

<!-- 过滤器 -->
{# 获取数据长度 #}
<p> {{ name_list | length }}</p>

{# 默认值 #}
<p>{{ value | default:'nothing' }}</p>

{# 将文件byte格式转换成一个人类可读的大小 #}
<p>{{ byte | default:3123232131 | filesizeformat }}</p>

{# 切片 #}
<p>{{ str | default:'hello world' | slice:'2:-1' }}</p>

{# 日期格式 #}
<p>{{ time | date:'Y-m-d H:i:s' }}</p>

{# 截断字符 truncatechars:9 实际显示8个字符 #}
<p>{{ word | default:'a b c d e f' | truncatechars:9 }}</p>

{# 截断单词 #}
<p>{{ word | default:'a b c d e f' | truncatewords:3 }}</p>

{# 移除所有与变量相同的字符串 #}
<p>{{ word | default:'a b c d e f' | cut:' ' }}</p>

{# 字符串拼接 #}
<p>{{ name_list | join:'+' }}</p>

{# safe 进一步转译为html(不安全) #}
{{ A }}
{{ A | safe }}

自定义过滤器

在当前app目录下创建一个templatetags(固定写法)文件夹,再随意创建xx.py文件

from django import template
from collections import Iterable
register = template.Library()  # register 固定的名字


# 注册过滤器(最多传2个参数)
@register.filter
def my_filter(v1, v2):
    rest = v1 + '---abc---' + v2
    return rest
{# 导入自定义模板文件(xx.py) #}
{% load my_filters %}
{# 使用自定义过滤器 #}
{{ s1 | my_filter:'123' }}

标签

内置标签

{# 标签 #}
{% for name in name_list %}
    xxx
    {{ forloop.counter }}
    {{ forloop.counter0 }}
    {{ forloop.revcounter0 }}
    {{ forloop.last }}
    {{ forloop.first }}
    {{ forloop.parentloop }}
{# 如果循环为空执行empty下面的内容 #}
{% empty %}
    xxxx
{% endfor %}

{% if name == '1' %}
    xxx
{% elif name == '2' %}
    xxx
{% else %}
    xxx
{% endif %}

{# with 起别名(只能在with语句内使用) #}
{% with name_list as names %}
    {{ names }}
{% endwith %}

{# csrf认证(写在form表单里面的任意位置) #}
{% csrf_token %}

自定义标签

py文件中

from django import template
from collections import Iterable
register = template.Library()  # register 固定的名字


# 注册标签(可以传多个参数)
@register.simple_tag
def my_tag(v1, v2, v3='a'):
    return f'自定义标签:{v1}--{v2}--{v3}'

html页面中

{# 导入自定义模板文件(xx.py) #}
{% load my_filters %}
<h3>
    {% my_tag s1 'abc' %}<br>
    {% my_tag s1 'abc' 123 %}
</h3>

自定义组件

# 自定义组件(可以传多个参数)
# 相当于 render 模板去渲染 inclusiontag 文件
@register.inclusion_tag('inclusiontag.html')
def func(data=None):
    if isinstance(data, Iterable):
        return {'data': data}
    else:
        return {'data': [1, 2, 3, 4]}

inclusiontag.html

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<ul>
    {% for i in data %}
        <li>{{ i }}</li>
    {% endfor %}
</ul>
</body>
</html>

页面中使用

{#使用inclusiontag#}
{% func %}