一、setting.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'app02.apps.App02Config', # 注册app 全写
'app01', # 注册app 简写
]
二、urls.py
1.urls.py
# urls.py
from django.contrib import admin
from django.urls import path, include
from app01 import urls as app01_urls
from app02 import urls as app02_urls
urlpatterns = [
path('admin/', admin.site.urls),
# 路由分发第一种写法
# path('app01/', include(app01_urls)),
# path('app02/', include(app02_urls)),
# 路由分发第二种写法
path('app01/', include('app01.urls')),
path('app02/', include('app02.urls')),
]
2.app01/urls.py
# app01/urls.py
from django.urls import path
from app01 import views
urlpatterns = [
path('reg.html', views.reg, name='app01_reg'), # 伪静态网页 增加浏览器搜索
path('home/', views.home), # 模板的继承
path('login/', views.login),
path('registration/', views.registration)
]
3.app02/urls.py
# app02/urls.py
from django.urls import path
from app02 import views
urlpatterns = [
path('reg/', views.reg, name='app02_reg'),
path('ab_json/', views.ab_json), # JsonResponse对象
path('ab_file/', views.ab_file), # 上传文件
path('login/', views.MyLogin.as_view()), # CBV路由 根据请求方式不同直接匹配到对应的方法执行
path('index/', views.index), # 模板层
]
三、views.py
1.app01/views.py
# app01/views.py
from django.shortcuts import render, HttpResponse, redirect, reverse
def reg(request):
return HttpResponse('app01/reg')
def home(request):
return render(request, 'home.html')
def login(request):
return render(request, 'login.html')
def registration(request):
return render(request, 'reg.html')
2.app02/views.py
# app02/views.py
from django.shortcuts import render, HttpResponse, redirect, reverse
from django.http import JsonResponse
from django.views import View
import json
def reg(request):
return HttpResponse('<h1>app02.reg</h1>')
def ab_json(request):
user_dict = {'username': 'zhangsan,你好', 'password': '123123', 'hobby': 'read'}
# 先转成json格式字符串
# json_str = json.dumps(user_dict,ensure_ascii=False) # ensure_ascii=False解决乱码
# 将该字符串返回
# return HttpResponse(json_str)
return JsonResponse(user_dict, json_dumps_params={'ensure_ascii': False}) # json_dumps_params={'ensure_ascii': False}解决乱码
def ab_file(request): # FBV
if request.method == 'POST':
# print(request.POST) # 只能获取普通的键值对数据 文件不行
print(request.FILES) # 获取文件数据
file_obj = request.FILES.get('file') # 文件对象
print(file_obj.name)
with open(file_obj.name, 'wb') as f: # 保存文件
for line in file_obj:
f.write(line)
return render(request, 'form.html')
class MyLogin(View): # CBV
def get(self, request):
return render(request, 'form.html')
def post(self, request):
return HttpResponse('post方法')
# 模板层
def index(request):
# 模板语法可以传递的后端python数据类型
n = 123
f = 3.14
s = '你好,世界'
l = ['aaa', 'bbb', 'ccc']
b = True
t = (1, 2, 3, 4, 5, 6, 7)
d = {'username': 'zhangsan', 'age': 100}
se = {111, 222, 333, 'aaa'}
def func():
print("我被执行了")
return 'hello world'
class MyClass(object):
def get_self(self):
return 'self'
@staticmethod
def get_func():
return 'func'
@staticmethod
def get_class():
return 'cls'
obj = MyClass()
file_size = 1231231
import datetime
current_time = datetime.datetime.now()
info = '科学家说:爱情是一种化学反应。哲学家说:爱是人生的原则和唯一的目的。程序员说:爱是永远无法用代码写出的程序。而我说:爱是一场只属于勇敢者的游戏,在无法存档的游戏里,希望每个人都能勇敢去爱,一路向前,找到属于你们的通关秘语。'
egl = 'my name is zhangsan my age is 100 and i am from China'
hhh = '<h1>你好,世界</h1>'
from django.utils.safestring import mark_safe
res = mark_safe('<h1>hello world</h1>') # 取消转义
return render(request, 'index.html', locals())
四、自定义过滤器、标签、inclusion_tag
1.在应用下创建一个名字"必须"叫templatetags文件夹
2.在该文件夹内创建"任意"名称的py文件 eg:mytag.py
3.在该py文件内"必须"先写下面两句话
from django import template
register = template.Library()
# mytag.py
from django import template
register = template.Library()
# 自定义过滤器(过滤器只能最多有两个参数)
@register.filter(name='sum')
def my_sum(v1, v2):
return v1 + v2
# 自定义标签(参数可以有多个)
@register.simple_tag(name='plus')
def index(a, b, c, d):
return f'{a}-{b}-{c}-{d}'
# 自定义inclusion_tag
@register.inclusion_tag('left_menu.html')
def left(n):
data = ['第{}项'.format(i) for i in range(n)]
return locals() # 将data传递给left_menu.html
五、模板的继承
模板的继承 先选好想要继承的模板页面
{% extends 'home.html' %}
继承了之后子页面跟模板页面长的一模一样 需要在模板页面上提前划定可以被修改的区域
{% block content %}
模板内容
{% endblock %}
子页面就可以声明想要修改划定了的区域
{% block content %}
子页面内容
{% endblock %}
一般情况下模板页面上应该至少有三块可以被修改的区域
1.css区域
{% block css %}
{% endblock %}
2.html区域
{% block content %}
{% endblock %}
3.js区域
{% block js %}
{% endblock %}
模板的导入:把wasd.html所有的代码都拷贝到页面上,相当于是一个模块
{% include 'wasd.html' %}
六、templates
1.form.html
# form.html
<form action="" method="post" enctype="multipart/form-data">
<p>username:<input type="text" name="username"></p>
<p>file:<input type="file" name="file"></p>
<input type="submit">
</form>
2.index.html
# index.html模板语法
<p>{{ n }}</p>
<p>{{ f }}</p>
<p>{{ s }}</p>
<p>{{ l }}</p>
<p>{{ l.2 }}</p>
<p>{{ b }}</p>
<p>{{ t }}</p>
<p>{{ d }}</p>
<p>{{ d.username }}</p>
<p>{{ se }}</p>
<p>传递函数名会自动加括号调用,但是模板语法不支持给函数额外的参数:{{ func }}</p>
<p>传类名的时候也会自动加括号调用(实例化):{{ MyClass }}</p>
<p>内部能够自动判断出当前的变量名是否可以加括号调用,如果可以就会自动执行 针对的是函数名和类名</p>
<p>{{ obj }}</p>
<p>{{ obj.get_self }}</p>
<p>{{ obj.get_func }}</p>
<p>{{ obj.get_class }}</p>
<h1>过滤器</h1>
<p>过滤器就类似于模板语法内置的 内置方法</p>
<p>统计字符长度:{{ s|length }}</p>
<p>默认值:{{ b|default:'前面有值用前面的,没有用后面的' }}</p>
<p>文件大小:{{ file_size|filesizeformat }}</p>
<p>日期格式化:{{ current_time|date:'Y-m-d H:i:s' }}</p>
<p>切片操作(支持步长):{{ l|slice:'0:4:2' }}</p>
<p>窃取字符(包含三个点):{{ info|truncatechars:'20' }}</p>
<p>窃取单词(不包含三个点 按照空格切):{{ egl|truncatewords:'9' }}</p>
<p>移除特定的字符:{{ egl|cut:' ' }}</p>
<p>拼接操作:{{ l|join:'@' }}</p>
<p>拼接操作(加法):{{ n|add:123 }}</p>
<p>拼接操作(加法):{{ s|add:info }}</p>
<p>取消转义:{{ hhh|safe }}</p>
<p>取消转义:{{ res }}</p>
<h1>标签</h1>
{% for i in l %}
{# <p>{{ forloop }}</p>#}
<p>{{ i }}</p>
{% endfor %}
{% if b %}
<p>if判断</p>
{% else %}
<p>else</p>
{% endif %}
{% for foo in l %}
{% if forloop.first %}
<p>这是第一次循环</p>
{% elif forloop.last %}
<p>这是最后一次</p>
{% else %}
<p>{{ foo }}</p>
{% endif %}
{% endfor %}
{% for key in d.keys %}
<p>{{ key }}</p>
{% endfor %}
{% for value in d.values %}
<p>{{ value }}</p>
{% endfor %}
{% for item in d.items %}
<p>{{ item }}</p>
{% endfor %}
{% with d.username as d_name %}
<p>{{ d_name }}</p>
在with语法内就可以通过后面的别名快速的使用到前面非常复杂获取数据的方式
<p>{{ d.username }}</p>
{% endwith %}
<h1>自定义的使用</h1>
{% load mytag %}
<p>{{ n|sum:666 }}</p>
标签多个参数彼此之间空格隔开
<p>{% plus 'zhangs' 123 123 123 %}</p>
当html页面某一个地方页面想要传参数才能够动态的渲染出来,并且在多个页面上都需要使用
到该局部 那么就考虑将该局部页面做成inclusion_tag形式
{% left 10 %}
3.left_menu.html
# 默认创建的都删掉只有以下代码
<ul>
{% for datum in data %}
<li>{{ datum }}</li>
{% endfor %}
</ul>
4.home.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div>
<nav class="navbar navbar-inverse">
<div class="container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse"
data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">Brand</a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li class="active"><a href="#">Link <span class="sr-only">(current)</span></a></li>
<li><a href="#">Link</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
aria-expanded="false">Dropdown <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">Separated link</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">One more separated link</a></li>
</ul>
</li>
</ul>
<form class="navbar-form navbar-left">
<div class="form-group">
<input type="text" class="form-control" placeholder="Search">
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
<ul class="nav navbar-nav navbar-right">
<li><a href="#">Link</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
aria-expanded="false">Dropdown <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">Separated link</a></li>
</ul>
</li>
</ul>
</div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</nav>
</div>
<div class="container-fluid">
<div class="row">
<div class="col-md-3">
<div class="list-group">
<a href="/app01/home/" class="list-group-item active">
首页
</a>
<a href="/app01/login/" class="list-group-item">登录</a>
<a href="/app01/registration/" class="list-group-item">注册</a>
</div>
</div>
<div class="col-md-9">
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title">Panel title</h3>
</div>
<div class="panel-body">
{% block content %}
<div class="jumbotron">
<h1>Hello, world!</h1>
<p>...</p>
<p><a class="btn btn-primary btn-lg" href="#" role="button">Learn more</a></p>
</div>
{% endblock %}
</div>
</div>
</div>
</div>
</div>
<script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</body>
</html>
5.login.html
# 默认创建的都删掉只有以下代码
{% extends 'home.html' %}
{% block content %}
<h1>登录页面</h1>
<form action="">
<p>username:<input type="text" class="form-control"></p>
<p>password:<input type="text" class="form-control"></p>
<input type="submit" class="btn btn-success">
</form>
{% endblock %}
6.reg.html
# 默认创建的都删掉只有以下代码
{% extends 'home.html' %}
{% block content %}
<h1>注册页面</h1>
<form action="">
<p>username:<input type="text" class="form-control"></p>
<p>password:<input type="text" class="form-control"></p>
<input type="submit" class="btn btn-danger">
</form>
{% endblock %}