使用Django REST框架构建博客API和自定义用户模型
API为当今大多数应用程序提供支持。在本教程中,我们将逐步介绍如何使用Django REST框架(DRF)和自定义用户模型构建博客API。
我们将创建两个应用:
- accounts → 用于身份验证和用户管理
- posts → 用于创建、列出和管理博客文章
项目设置
首先,创建并激活虚拟环境:
1
2
3
|
mkdir blog_api && cd blog_api
python -m venv venv
source venv/bin/activate # Linux/macOS
|
安装Django、DRF和CORS头:
1
|
pip install django djangorestframework django-cors-headers
|
启动新的Django项目:
1
|
django-admin startproject django_project
|
创建应用:
1
2
|
python manage.py startapp accounts
python manage.py startapp posts
|
在django_project/settings.py中添加它们:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
"rest_framework",
"corsheaders",
"accounts",
"posts",
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'corsheaders.middleware.CorsMiddleware',#new
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
# CORS设置
CORS_ALLOWED_ORIGINS = [
"http://localhost:3000", # React默认
"http://127.0.0.1:3000",
"http://localhost:8080", # Vue默认
"http://127.0.0.1:8080",
]
# 仅用于开发 - 允许所有来源
# CORS_ALLOW_ALL_ORIGINS = True
|
自定义用户模型(accounts应用)
在accounts/models.py中:
1
2
3
4
5
6
7
8
9
|
from django.db import models
from django.contrib.auth.models import AbstractUser
# 创建你的模型
class CustomUser(AbstractUser):
name = models.CharField(max_length=100, blank=True, null=True)
def __str__(self):
return self.username
|
更新django_project/settings.py以使用自定义用户模型:
1
|
AUTH_USER_MODEL = "accounts.CustomUser"
|
这告诉Django在整个项目中使用我们的CustomUser模型而不是默认的User模型进行身份验证和用户管理。
管理员配置
更新accounts/admin.py以使用自定义表单:
自定义用户表单
创建accounts/forms.py用于Django管理员集成:
1
2
3
4
5
6
7
8
9
10
11
12
|
from django.contrib.auth.forms import UserCreationForm, UserChangeForm
from .models import CustomUser
class CustomUserCreationForm(UserCreationForm):
class Meta(UserCreationForm.Meta):
model = CustomUser
fields = UserCreationForm.Meta.fields + ('name',)
class CustomUserChangeForm(UserChangeForm):
class Meta:
model = CustomUser
fields = UserChangeForm.Meta.fields
|
管理员配置
更新accounts/admin.py以使用自定义表单:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
from django.contrib import admin
from .models import CustomUser
from .forms import CustomUserCreationForm, CustomUserChangeForm
from django.contrib.auth.admin import UserAdmin
# 注册你的模型
class CustomUserAdmin(UserAdmin):
add_form = CustomUserCreationForm
form = CustomUserChangeForm
model = CustomUser
list_display = ['username', 'email', 'name', 'is_staff']
fieldsets = UserAdmin.fieldsets + (
(None, {'fields': ('name',)}),
)
add_fieldsets = UserAdmin.add_fieldsets + (
(None, {'fields': ('name',)}),
)
search_fields = ('email', 'username', 'name')
# 使用模型注册管理类
admin.site.register(CustomUser, CustomUserAdmin)
|
博客文章(posts应用)
在posts/models.py中:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
from django.db import models
from django.conf import settings
# 创建你的模型
class Post(models.Model):
title = models.CharField(max_length=50)
content = models.TextField()
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return self.title
|
序列化器和视图
在posts/serializers.py中:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
from rest_framework import serializers
from .models import Post
class PostSerializer(serializers.ModelSerializer):
class Meta:
model = Post
fields = (
'id',
'title',
'content',
'author',
'created_at',
'updated_at'
)
|
在posts/views.py中:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
from django.shortcuts import render
from rest_framework import generics
from .models import Post
from .serializers import PostSerializer
# 创建你的视图
class PostList(generics.ListCreateAPIView):
queryset = Post.objects.all()
serializer_class = PostSerializer
class PostDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = Post.objects.all()
serializer_class = PostSerializer
|
在posts/urls.py中:
1
2
3
4
5
6
7
|
from django.urls import path
from .views import PostList, PostDetail
urlpatterns = [
path("posts/", PostList.as_view(), name="post-list"),
path("posts/<int:pk>/", PostDetail.as_view(), name="post-detail"),
]
|
在django_project/urls.py中:
1
2
3
4
5
6
7
|
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path("admin/", admin.site.urls),
path("api/", include("posts.urls")),
]
|
运行API
应用迁移并创建超级用户:
1
2
3
|
python manage.py makemigrations
python manage.py migrate
python manage.py createsuperuser
|
按照提示创建管理员用户 - 您将被要求输入:
- 用户名
- 电子邮件地址(可选)
- 姓名(可选 - 我们的自定义字段)
- 密码
然后运行服务器:
1
|
python manage.py runserver
|
您现在可以:
- 在http://127.0.0.1:8000/api/访问API
- 使用超级用户凭据在http://127.0.0.1:8000/admin/登录Django管理员
- 通过管理界面管理用户和文章
现在测试端点:
- GET /api/posts/ → 列出文章
- POST /api/posts/ → 创建新文章
- GET /api/posts// → 检索特定文章
- PUT /api/posts// → 更新文章
- DELETE /api/posts// → 删除文章
测试您的API
您可以使用以下工具测试API:
- Postman - 用于API测试的GUI界面
- curl - 命令行工具
使用curl创建文章的示例:
1
2
3
4
5
6
7
|
curl -X POST http://127.0.0.1:8000/api/posts/ \
-H "Content-Type: application/json" \
-d '{
"title": "我的第一篇博客文章",
"content": "这是我第一篇博客文章的内容!",
"author": 1
}'
|
编写单元测试
在posts/tests.py中创建全面的测试:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
from django.test import TestCase
from .models import Post
from django.contrib.auth import get_user_model
# 创建你的测试
class BlogTests(TestCase):
@classmethod
def setUpTestData(cls):
cls.user = get_user_model().objects.create_user(
username='testuser',
email='test@gmail.com',
password='secret'
)
cls.post = Post.objects.create(
title='A good title',
content='Nice content',
author=cls.user,
)
def test_post_model(self):
self.assertEqual(self.post.title, 'A good title')
self.assertEqual(self.post.content, 'Nice content')
self.assertEqual(self.post.author.username, 'testuser')
self.assertEqual(str(self.post), 'A good title')
|
运行测试:
后续步骤
从这里,您可以使用以下功能扩展API:
- 身份验证(JWT/基于会话)
- 权限(谁可以创建/编辑文章)
- 部署
- 使用DRF的可浏览API或Swagger进行API文档编写
- 前端集成 - 现在已准备好用于React、Vue或Angular应用!
结论
您现在拥有一个功能齐全的博客API,具有:
- 用于灵活性的自定义用户模型
- 博客文章的完整CRUD操作
- 清晰、可维护的代码结构
这个基础为构建更复杂的博客应用程序或学习高级Django REST框架概念提供了一个坚实的起点。
您会向此博客API添加哪些功能?在下面的评论中分享您的想法!
编码愉快!