###1. 内容回顾
- 1.HTTP
- 请求
- 请求行 请求头 请求数据
- 响应
- 响应行 响应头 响应体
- 2.Django
- 1.Django的命令
- 下载安装
- pip install django==1.11.22 -i 源
- 创建项目
- django-admin startproject 项目名
- 启动项目
- 切换到项目的根目录 manage.py
- python manage.py runserver # 127.0.0.1:8000
- python manage.py runserver 80 # 127.0.0.1:80
- python manage.py runserver 0.0.0.0:80 # 0.0.0.0:80
- 创建APP
- python manage.py startapp app名称
- 数据库迁移的命令
- python manage.py makemigrations # 记录models的变更记录
- python manage.py migrate # 执行迁移 将变更记录同步到数据库中
- 2.Django的配置
- BASE_DIR 项目的根目录
- 注册的APP
```python
INSTALLED_APPS = [
'app01'
'app01.apps.App01Config',
]
```
- MIDDLEWARE 中间件
```python
'django.middleware.csrf.CsrfViewMiddleware' # 注释掉 提交POST请求
```
- TEMPLATES 模板
```python
'DIRS': [os.path.join(BASE_DIR, 'templates')]
```
- DATABASES 数据库
```python
'ENGINE': 'django.db.backends.mysql',
'NAME': 'day14',
'HOST': '127.0.0.1',
'PORT': 3306,
'USER': 'root',
'PASSWORD': '666',
```
- 静态文件
```python
STATIC_URL = '/static/' # '/static/css/sss.css'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static')
]
```
###2.今日内容
- 路由系统进阶:
- https://www.cnblogs.com/maple-shaw/articles/9282718.html
- 动态路由
^ $ [0-9] [a-z] [A-Z] w d {4} ? + * .
- 分组、命名分组
- 分组
```python
url(r'^blog/([0-9]{4})/$', views.blog),
```
- 捕获的参数按照 位置参数 传递给函数
- 命名分组
```python
url(r'^blog/(?P<year>[0-9]{4})/$', views.blog),
```
- 捕获的参数按照 关键字参数 传递给函数
- include
```python
url(r'^', include('app01.urls')),
```
- URL命名和反向解析 **
- 命名
```python
url(r'^publisher/$', views.publisher_list,name='publisher_list'),
```
- 反向解析
- 模板
```python
{% url 'publisher_list' %} ——》 '/app01/publisher/'
```
- python文件
```python
from django.shortcuts import reverse
from django.urls import reverse
reverse('publisher_list') ——》 '/app01/publisher/'
```
- 分组
- 命名
```python
url(r'^edit_publisher/(d+)/$', views.edit_publisher,name='edit_publisher'),
```
- 反向解析
- 模板
```html
{% url 'edit_publisher' 2 %} ——》 '/app01/edit_publisher/2/'
```
- python文件
```python
from django.shortcuts import reverse
from django.urls import reverse
reverse('edit_publisher', args=('100',)) ——》 '/app01/edit_publisher/100/'
```
- 命名分组
- 命名
```python
url(r'^edit_publisher/(?P<pk>d+)/$', views.edit_publisher,name='edit_publisher'),
```
- 反向解析
- 模板
```html
{% url 'edit_publisher' 2 %} ——》 '/app01/edit_publisher/2/'
{% url 'edit_publisher' pk=publisher.pk %}
```
- python文件
```python
from django.shortcuts import reverse
from django.urls import reverse
reverse('edit_publisher', args=('100',)) ——》 '/app01/edit_publisher/100/'
reverse('edit_publisher', kwargs={'pk':'12'})
```
- namespace
- 避免name重复
```python
url(r'^app01/', include('app01.urls', namespace='app01')),
url(r'^app02/', include('app02.urls', namespace='app02')),
```
```python
reverse('namespace:name')
```
###视图函数进阶:
- https://www.cnblogs.com/maple-shaw/articles/9285269.html
- FBV 视图里基于函数处理请求(Function Based View)
- CBV 视图里基于类处理请求(Class Based View)
- 定义:
```python
from django.views import View
class AddPublisher(View):
def get(self, request, *args, **kwargs):
# get 业务逻辑
return response
def post(self, request, *args, **kwargs):
# post 业务逻辑
return response
```
- 使用:
```python
url(r'^publisher/add/$', views.AddPublisher.as_view(), name='add_publisher'),
```
- 装饰器的使用
- FBV 直接加
- CBV
```python
from django.utils.decorators import method_decorator
```
- 1.加在方法上
```python
@method_decorator(timer)
def get(self, request, *args, **kwargs):
```
- 2.加在dispatch方法上,重新父类的dispatch方法
```python
@method_decorator(timer)
def dispatch(self, request, *args, **kwargs):
return super().dispatch(request, *args, **kwargs)
```
- 3.加在dispatch方法上,不需要重写父类的dispatch方法,带参数的装饰器
```python
@method_decorator(timer, name='dispatch')
class AddPublisher(View):
```
- 4.加在类上
```python
@method_decorator(timer, name='post')
@method_decorator(timer, name='get')
class AddPublisher(View):
```
- 请求和响应
- Request
- 属性
- request.GET
- request.POST
- request.FILES
- request.COOKIES
- request.session
- request.method
- request.path_info 路径 不包含域名和IP 也不包含URL的参数
- request.body 请求体 bytes
- request.META 头信息
- 方法
- request.get_full_path() 路径 不包含域名和IP 包含URL的参数
- request.is_ajax()
- Response
- HttpResponse('xxxxx') ——》 返回字符串
- render(request,'模板的文件名',{}) ——》 返回一个完整的HTML页面
- redirect('重定向的地址') ——》 重定向
- from django.http.response import JsonResponse
- JsonResponse({})
- JsonResponse(['1', 2, 4],safe=False) # 非字典类型
###模板引擎进阶:
- https://www.cnblogs.com/maple-shaw/articles/9333821.html
- 变量
- {{ 变量 }}
- .key
- .属性
- .方法 不加括号
- .索引
- 过滤器
- {{ 变量|过滤器的名字 }}
- {{ 变量|过滤器的名字:参数 }}
- default
- safe
- date
- 标签
- csrf_token 跨站请求攻击盾牌(Cross site request forgery)
{% csrf_token %} 放在form标签中
- 母板和继承
- 组件
- 静态文件相关
```html
{% load static %}
<link rel="stylesheet" href="{% static 'plugins/bootstrap-3.3.7/css/bootstrap.min.css' %}">
<link rel="stylesheet" href="{% static 'css/dashboard.css' %}">
```
- 外键
- 关联 描述多对一的关系
```python
class Publisher(models.Model):
name = models.CharField(max_length=32)
class Book(models.Model):
title = models.CharField(max_length=32)
pub = models.ForeignKey(Publisher, on_delete=models.CASCADE)
```
```python
all_books = models.Book.objects.all()
for book in all_books:
print(book)
print(book.title)
print(book.pub) # 所关联的对象
print(book.pub.name) # 所关联的对象的name
print(book.pub_id) # 所关联的对象id
print('*' * 20)
```
- 添加
```python
models.Book.objects.create(title=book_name,pub=models.Publisher.objects.filter(pk=pub_id).first())
models.Book.objects.create(title=book_name, pub_id=pub_id)
```
- 编辑
```python
book_obj = models.Book.objects.filter(pk=pk).first()
book_name = request.POST.get('book_name')
pub_id = request.POST.get('pub_id')
book_obj.title = book_name
# book_obj.pub = models.Publisher.objects.filter(pk=pub_id).first()
book_obj.pub_id = pub_id
book_obj.save()
```