Django基础
什么是Django
在python中有很多web框架,如Django、Flask、Tornado。Django和其他web框架相比,功能更加齐全。
Django遵循MVC框架模式,即模型(M),视图(V),控制器(C)
下载Django
pip install django=2.2
创建一个django项目
使用Pycharm创建Django项目
![](https://img2020.cnblogs.com/blog/1579919/202005/1579919-20200523212424209-631939506.png)
命令行创建
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目录结构
![](https://img2020.cnblogs.com/blog/1579919/202005/1579919-20200523212448676-39708022.png)
启动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 %}