$ cat ~/articles/110 _

快速开始 django 项目

作者:jaifire 2025-02-25 14:13 0 阅读

创建项目

# 在 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攻击原理:

攻击流程:

  1. 用户登录银行网站A,获得cookie
  2. 用户访问恶意网站B
  3. 网站B包含向网站A转账的表单,自动提交
  4. 因为有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,恶意网站无法获取,请求被拒绝。