创建项目
# 在 djangotutorial 目录内创建一个名为 mysite 的项目
django-admin startproject mysite djangotutorial
初始配置
- 创建 app:
python manage.py startapp app_name # 默认情况下,会在项目根目录下建app,如里需要把 app 集中在一个目录下,需要进入该目录后执行 python ../manage.py startapp sixmwt - 如果是在 app 目录下创建的应用,需要修改
apps.py的配置from django.apps import AppConfig
class SixmwtConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'app.sixmwt' # 修改 sixmwt 为 app.sixmwt
- 配置 `settings.py`
```python
ALLOWED_HOSTS = ["*"]
INSTALLED_APPS = [
# 'django.contrib.admin',
# 'django.contrib.auth',
# 'django.contrib.contenttypes',
# 'django.contrib.sessions',
# 'django.contrib.messages',
# 'django.contrib.staticfiles',
#
'app.sixmwt',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
# 'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
# 'django.contrib.auth.middleware.AuthenticationMiddleware',
# 'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
运行项目
python manage.py runserver
# 默认运行在 `http://127.0.0.1:8000/`,可加端口:
python manage.py runserver 8080
创建项目APP
URL与视图的映射
在 app/urls.py 中写:
path('hello/', views.hello), # 不能以 / 开头
或
path('blog/', include('app.urls'))
# 注意,不同模块的路由可能有相同的别名,可以用 app_name 区别开,加了app_name 后别名的使用方法为:
reverse('blog:detail', args=[1])
path() 的 route 参数匹配规则
path('<类型:变量名>/', views.xxx)
| 类型 | 说明 | 示例路径 |
|---|---|---|
str |
非空字符串(不含 /) |
<str:name>/ |
int |
整数 | <int:id>/ |
slug |
字母、数字、-、_ 组成 |
<slug:slug>/ |
uuid |
UUID 对象 | <uuid:uid>/ |
path |
可包含 / 的字符串 |
<path:subpath>/ |
path() 的 name 参数
# 定义方式
path('blog/<int:id>/', views.detail, name='blog-detail')
# 模板中生成链接
<a href="{% url 'blog-detail' blog.id %}">查看</a>
# **视图中反向解析 URL**:
from django.urls import reverse
url = reverse('blog-detail', args=[123])
# 重定向时使用
return redirect('blog-detail', blog.id)
2、settings.py 中注册app:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
# 你的自定义app
'blog', # 方式1:直接app名
'accounts.apps.AccountsConfig', # 方式2:完整路径
]
F和Q表达式
F表达式(字段引用):
from django.db.models import F
# 价格增加10
Product.objects.update(price=F('price') + 10)
# 字段比较
Article.objects.filter(views__gt=F('likes'))
# 字段运算
User.objects.annotate(full_score=F('math_score') + F('english_score'))
Q表达式(复杂查询):
from django.db.models import Q
# AND
User.objects.filter(Q(age__gte=18) & Q(status='active'))
# OR
User.objects.filter(Q(name__contains='张') | Q(name__contains='李'))
# NOT
User.objects.filter(~Q(status='deleted'))
# 复杂组合
User.objects.filter(Q(age__gte=18) & (Q(city='北京') | Q(city='上海')))
其它表达式:
Case/When- 条件表达式Exists- 存在性查询Subquery- 子查询OuterRef- 外部引用Window- 窗口函数
最常用的就是F和Q。
Cookie和Session示例:
Cookie使用:
# 设置cookie
def set_cookie(request):
response = HttpResponse('Cookie设置成功')
response.set_cookie('username', '张三', max_age=3600) # 1小时
return response
# 读取cookie
def get_cookie(request):
username = request.COOKIES.get('username', '未设置')
return HttpResponse(f'用户名: {username}')
# 删除cookie
def delete_cookie(request):
response = HttpResponse('Cookie删除成功')
response.delete_cookie('username')
return response
Session使用:
# 设置session
def set_session(request):
request.session['user_id'] = 123
request.session['username'] = '张三'
return HttpResponse('Session设置成功')
# 读取session
def get_session(request):
user_id = request.session.get('user_id', '未登录')
return HttpResponse(f'用户ID: {user_id}')
# 删除session
def logout(request):
request.session.flush() # 清空所有session
# 或者删除特定key
# del request.session['user_id']
return HttpResponse('退出成功')
CSRF攻击原理:
攻击流程:
- 用户登录银行网站A,获得cookie
- 用户访问恶意网站B
- 网站B包含向网站A转账的表单,自动提交
- 因为有cookie,银行认为是用户操作,转账成功
解决方法
模板中:
<form method="post">
{% csrf_token %} <!-- 必须加这个 -->
<input type="text" name="username">
<button type="submit">提交</button>
</form>
Ajax请求:
// 获取token
const token = document.querySelector('[name=csrfmiddlewaretoken]').value;
// 发送请求
fetch('/api/', {
method: 'POST',
headers: {
'X-CSRFToken': token,
'Content-Type': 'application/json',
},
body: JSON.stringify({data: 'test'})
});
设置豁免(不推荐):
from django.views.decorators.csrf import csrf_exempt
@csrf_exempt
def api_view(request):
return JsonResponse({'status': 'ok'})
原理: Django生成随机token,恶意网站无法获取,请求被拒绝。