Django 社交网络应用教程
1. Django 简介和特性
Django 是一个高级 Python Web 框架,它鼓励快速开发和干净、实用的设计。Django 遵循 MVT(Model-View-Template)架构,提供了许多内置功能,如用户认证、内容管理、表单处理、缓存等。
主要特性:
- ORM(对象关系映射):简化数据库操作。
- 自动管理界面:快速生成管理后台。
- URL 路由:灵活的 URL 设计。
- 模板系统:强大的模板引擎。
- 表单处理:简化表单创建和验证。
- 安全性:内置安全机制,如 CSRF 保护。
2. 安装和环境设置
安装 Django
pip install django
创建项目
django-admin startproject social_network
cd social_network
运行开发服务器
python manage.py runserver
3. 项目结构和管理命令
项目结构
social_network/
manage.py
social_network/
__init__.py
settings.py
urls.py
asgi.py
wsgi.py
常用管理命令
- 创建应用:
python manage.py startapp app_name - 数据库迁移:
python manage.py makemigrations和python manage.py migrate - 创建超级用户:
python manage.py createsuperuser
4. MVT 架构
Model
- 定义数据结构和行为。
- 使用 ORM 进行数据库操作。
View
- 处理业务逻辑。
- 接收请求并返回响应。
Template
- 负责展示数据。
- 使用 Django 模板语言。
5. 第一个 Django 应用
创建应用
python manage.py startapp posts
定义模型
# posts/models.py
from django.db import models
class Post(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
注册模型
# posts/admin.py
from django.contrib import admin
from .models import Post
admin.site.register(Post)
创建视图
# posts/views.py
from django.shortcuts import render
from .models import Post
def post_list(request):
posts = Post.objects.all()
return render(request, 'posts/post_list.html', {'posts': posts})
配置 URL
# posts/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.post_list, name='post_list'),
]
创建模板
<!-- posts/templates/posts/post_list.html -->
<h1>Posts</h1>
<ul>
{% for post in posts %}
<li>{{ post.title }}</li>
{% endfor %}
</ul>
6. 模型定义和字段类型
常用字段类型
CharField:字符字段。TextField:文本字段。IntegerField:整数字段。DateTimeField:日期时间字段。ForeignKey:外键。ManyToManyField:多对多关系。
示例
class Comment(models.Model):
post = models.ForeignKey(Post, on_delete=models.CASCADE)
content = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
7. 数据库迁移
创建迁移文件
python manage.py makemigrations
应用迁移
python manage.py migrate
8. 查询集和管理器
查询集
all():获取所有对象。filter():过滤对象。exclude():排除特定对象。order_by():排序对象。
管理器
- 自定义管理器可以添加额外的方法。
class PostManager(models.Manager):
def published(self):
return self.filter(published=True)
class Post(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
published = models.BooleanField(default=False)
objects = PostManager()
9. 模型关系
一对多关系
class Author(models.Model):
name = models.CharField(max_length=100)
class Book(models.Model):
title = models.CharField(max_length=200)
author = models.ForeignKey(Author, on_delete=models.CASCADE)
多对多关系
class Tag(models.Model):
name = models.CharField(max_length=50)
class Article(models.Model):
title = models.CharField(max_length=200)
tags = models.ManyToManyField(Tag)
10. 自定义模型方法
class Post(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
def get_summary(self):
return self.content[:100]
11. 函数视图和类视图
函数视图
def post_detail(request, post_id):
post = get_object_or_404(Post, id=post_id)
return render(request, 'posts/post_detail.html', {'post': post})
类视图
from django.views import View
class PostDetailView(View):
def get(self, request, post_id):
post = get_object_or_404(Post, id=post_id)
return render(request, 'posts/post_detail.html', {'post': post})
12. URL 模式和命名
URL 模式
urlpatterns = [
path('posts/', views.post_list, name='post_list'),
path('posts/<int:post_id>/', views.post_detail, name='post_detail'),
]
命名 URL
<a href="{% url 'post_detail' post.id %}">View Post</a>
13. 视图参数和请求处理
请求对象
def post_detail(request, post_id):
if request.method == 'POST':
# 处理 POST 请求
else:
# 处理 GET 请求
14. 通用视图
示例
from django.views.generic import ListView, DetailView
class PostListView(ListView):
model = Post
template_name = 'posts/post_list.html'
context_object_name = 'posts'
class PostDetailView(DetailView):
model = Post
template_name = 'posts/post_detail.html'
context_object_name = 'post'
15. 中间件
自定义中间件
class CustomMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
# 请求处理前的逻辑
response = self.get_response(request)
# 响应处理后的逻辑
return response
16. 模板语法和标签
模板语法
<h1>{{ post.title }}</h1>
<p>{{ post.content }}</p>
模板标签
{% for post in posts %}
<h2>{{ post.title }}</h2>
<p>{{ post.content }}</p>
{% endfor %}
17. 模板继承
基础模板
<!-- base.html -->
<html>
<head>
<title>{% block title %}My Site{% endblock %}</title>
</head>
<body>
<header>...</header>
<main>
{% block content %}{% endblock %}
</main>
<footer>...</footer>
</body>
</html>
子模板
<!-- post_list.html -->
{% extends 'base.html' %}
{% block title %}Posts{% endblock %}
{% block content %}
<h1>Posts</h1>
<ul>
{% for post in posts %}
<li>{{ post.title }}</li>
{% endfor %}
</ul>
{% endblock %}
18. 上下文处理器
自定义上下文处理器
# context_processors.py
def custom_context(request):
return {'custom_var': 'Custom Value'}
配置上下文处理器
# settings.py
TEMPLATES = [
{
'OPTIONS': {
'context_processors': [
'social_network.context_processors.custom_context',
],
},
},
]
19. 自定义模板标签和过滤器
自定义过滤器
# templatetags/custom_filters.py
from django import template
register = template.Library()
@register.filter
def upper_case(value):
return value.upper()
使用过滤器
{{ post.title|upper_case }}
20. 静态文件处理
配置静态文件
# settings.py
STATIC_URL = '/static/'
STATICFILES_DIRS = [
BASE_DIR / "static",
]
使用静态文件
{% load static %}
<link rel="stylesheet" href="{% static 'css/styles.css' %}">
21. Django Form 类
定义表单
from django import forms
class PostForm(forms.Form):
title = forms.CharField(max_length=200)
content = forms.CharField(widget=forms.Textarea)
使用表单
def create_post(request):
if request.method == 'POST':
form = PostForm(request.POST)
if form.is_valid():
# 处理表单数据
title = form.cleaned_data['title']
content = form.cleaned_data['content']
Post.objects.create(title=title, content=content)
return redirect('post_list')
else:
form = PostForm()
return render(request, 'posts/create_post.html', {'form': form})
22. 表单验证
自定义验证
class PostForm(forms.Form):
title = forms.CharField(max_length=200)
content = forms.CharField(widget=forms.Textarea)
def clean_title(self):
title = self.cleaned_data['title']
if len(title) < 5:
raise forms.ValidationError("Title must be at least 5 characters long.")
return title
23. ModelForm
定义 ModelForm
from django.forms import ModelForm
class PostForm(ModelForm):
class Meta:
model = Post
fields = ['title', 'content']
使用 ModelForm
def create_post(request):
if request.method == 'POST':
form = PostForm(request.POST)
if form.is_valid():
form.save()
return redirect('post_list')
else:
form = PostForm()
return render(request, 'posts/create_post.html', {'form': form})
24. 表单集 (Formsets)
定义表单集
from django.forms import formset_factory
PostFormSet = formset_factory(PostForm, extra=2)
使用表单集
def manage_posts(request):
if request.method == 'POST':
formset = PostFormSet(request.POST)
if formset.is_valid():
for form in formset:
if form.cleaned_data:
form.save()
return redirect('post_list')
else:
formset = PostFormSet()
return render(request, 'posts/manage_posts.html', {'formset': formset})
25. 文件上传处理
配置文件上传
# settings.py
MEDIA_URL = '/media/'
MEDIA_ROOT = BASE_DIR / 'media'
定义模型
class Post(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
image = models.ImageField(upload_to='posts/')
处理文件上传
def create_post(request):
if request.method == 'POST':
form = PostForm(request.POST, request.FILES)
if form.is_valid():
form.save()
return redirect('post_list')
else:
form = PostForm()
return render(request, 'posts/create_post.html', {'form': form})
26. 用户认证系统
用户注册
from django.contrib.auth.forms import UserCreationForm
def register(request):
if request.method == 'POST':
form = UserCreationForm(request.POST)
if form.is_valid():
form.save()
return redirect('login')
else:
form = UserCreationForm()
return render(request, 'registration/register.html', {'form': form})
用户登录
from django.contrib.auth import authenticate, login
def user_login(request):
if request.method == 'POST':
username = request.POST['username']
password = request.POST['password']
user = authenticate(request, username=username, password=password)
if user is not None:
login(request, user)
return redirect('post_list')
else:
# 处理错误
pass
return render(request, 'registration/login.html')
27. 自定义用户模型
定义自定义用户模型
from django.contrib.auth.models import AbstractUser
class CustomUser(AbstractUser):
bio = models.TextField(max_length=500, blank=True)
配置自定义用户模型
# settings.py
AUTH_USER_MODEL = 'accounts.CustomUser'
28. 权限和组
定义权限
from django.contrib.auth.models import Permission
permission = Permission.objects.get(codename='can_publish')
分配权限
user.user_permissions.add(permission)
29. 登录、注销和注册视图
登录视图
from django.contrib.auth.views import LoginView
urlpatterns = [
path('login/', LoginView.as_view(template_name='registration/login.html'), name='login'),
]
注销视图
from django.contrib.auth.views import LogoutView
urlpatterns = [
path('logout/', LogoutView.as_view(), name='logout'),
]
注册视图
from django.contrib.auth.forms import UserCreationForm
from django.views.generic.edit import CreateView
class RegisterView(CreateView):
form_class = UserCreationForm
template_name = 'registration/register.html'
success_url = '/login/'
30. 基于类的权限控制
权限检查
from django.contrib.auth.mixins import UserPassesTestMixin
class PostDetailView(UserPassesTestMixin, DetailView):
model = Post
template_name = 'posts/post