创建项目的步骤
首先创建一个py项目比如名字叫blog
安装django pip install django==3.2
安装drf pip install djangorestframework
settings的配置如下 特别主要匿名用户的配置
settings配置:
"""
Django settings for blog project.
Generated by 'django-admin startproject' using Django 4.2.21.
For more information on this file, see
https://docs.djangoproject.com/en/4.2/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/4.2/ref/settings/
"""
from pathlib import Path
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/4.2/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = "django-insecure-2t+3c@1b%a)(!z5-^mh0x20i^!y4nx5)ax1s#nxvc9nd59j7-^"
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
# "django.contrib.admin",
# "django.contrib.auth",
# "django.contrib.contenttypes",
# "django.contrib.sessions",
# "django.contrib.messages",
"django.contrib.staticfiles",
"rest_framework",
"api.apps.ApiConfig"
]
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",
]
ROOT_URLCONF = "blog.urls"
TEMPLATES = [
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [],
"APP_DIRS": True,
"OPTIONS": {
"context_processors": [
"django.template.context_processors.debug",
"django.template.context_processors.request",
# "django.contrib.auth.context_processors.auth",
# "django.contrib.messages.context_processors.messages",
],
},
},
]
WSGI_APPLICATION = "blog.wsgi.application"
# Database
# https://docs.djangoproject.com/en/4.2/ref/settings/#databases
DATABASES = {
"default": {
"ENGINE": "django.db.backends.sqlite3",
"NAME": BASE_DIR / "db.sqlite3",
}
}
# Password validation
# https://docs.djangoproject.com/en/4.2/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator",
},
{
"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator",
},
{
"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator",
},
{
"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator",
},
]
# Internationalization
# https://docs.djangoproject.com/en/4.2/topics/i18n/
LANGUAGE_CODE = "en-us"
TIME_ZONE = "UTC"
USE_I18N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/4.2/howto/static-files/
STATIC_URL = "static/"
# Default primary key field type
# https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
from rest_framework.request import Request
REST_FRAMEWORK ={
"UNAUTHENTICATED_USER": None,
}
# url的配置
from django.urls import path
from api import views
urlpatterns = [
# path("admin/", admin.site.urls),
# path("db/", views.db),
path("api/blog/", views.BlogView.as_view()),
path("api/blog/<int:pk>/", views.BlogDetailView.as_view()),
path("api/comment/<int:blog_id>/", views.CommentView.as_view()),
path("api/register/", views.RegisterView.as_view()),
path("api/login/", views.LoginView.as_view()),
]
认证组件的配置:
"""
☯️ 道生一,一生二,二生三,三生万物 ☯️
----------------------------------------------------------------
@Author : 叶青
@Date : 2025/5/14 16:39
@Purpose : 文件的具体功能描述
钱难赚,屎难吃 : 你有多自律,就有多自由 心中无敌便无敌于天下
----------------------------------------------------------------
☯️ 代码亦有道,一动一静皆自然 ☯️
"""
from rest_framework.authentication import BaseAuthentication
from api import models
from rest_framework import exceptions
class BlogAuthentication(BaseAuthentication):
def authenticate(self, request):
token = request.query_params.get("token")
if not token:
return
instance = models.UserInfo.objects.filter(token=token).first()
if not instance:
return
return instance, token
def authenticate_header(self, request):
return "API"
class Nouthentication(BaseAuthentication):
def authenticate(self, request):
raise exceptions.AuthenticationFailed({"code": 2000, "error": "认证失败"})
def authenticate_header(self, request):
return "API"
hook定制化的内容:
"""
☯️ 道生一,一生二,二生三,三生万物 ☯️
----------------------------------------------------------------
@Author : 叶青
@Date : 2025/5/14 16:39
@Purpose : 文件的具体功能描述
钱难赚,屎难吃 : 你有多自律,就有多自由 心中无敌便无敌于天下
----------------------------------------------------------------
☯️ 代码亦有道,一动一静皆自然 ☯️
"""
from rest_framework.authentication import BaseAuthentication
from api import models
from rest_framework import exceptions
class BlogAuthentication(BaseAuthentication):
def authenticate(self, request):
token = request.query_params.get("token")
if not token:
return
instance = models.UserInfo.objects.filter(token=token).first()
if not instance:
return
return instance, token
def authenticate_header(self, request):
return "API"
class Nouthentication(BaseAuthentication):
def authenticate(self, request):
raise exceptions.AuthenticationFailed({"code": 2000, "error": "认证失败"})
def authenticate_header(self, request):
return "API"
整个view的函数
import uuid
from django.shortcuts import render,HttpResponse
from api import models
# Create your views here.
from rest_framework.views import APIView
from rest_framework import serializers
from rest_framework.response import Response
from rest_framework import exceptions
from ext.auth import BlogAuthentication,Nouthentication
from ext.hook import NbHookSerializer
class BlogUserSerializers(serializers.ModelSerializer):
class Meta:
model = models.UserInfo
fields = ["id", "username"]
class BlogSerializers(NbHookSerializer, serializers.ModelSerializer):
ctime = serializers.DateTimeField(format="%Y-%m-%d", read_only=True)
creator = BlogUserSerializers(read_only=True)
class Meta:
model = models.Blog
fields = ['id', "category", "image", "title", "text", "summary", "ctime", "comment_count", "favor_count",
"creator"]
extra_kwargs = {
"comment_count": {"read_only": True},
"favor_count": {"read_only": True},
"text": {"write_only": True},
}
def nb_category(self, obj):
return obj.get_category_display()
class BlogDetailSerializers(serializers.ModelSerializer):
category = serializers.CharField(source="get_category_display")
ctime = serializers.DateTimeField(format="%Y-%m-%d")
create_name = serializers.CharField(source="creator.username")
class Meta:
model = models.Blog
fields = "__all__"
def db(request):
models.Comment.objects.create(blog_id=1,content="测试1",user_id=1)
models.Comment.objects.create(blog_id=2, content="测试2", user_id=2)
return HttpResponse("成功")
# v1 = models.UserInfo.objects.create(username="叶青",password="123")
# v2 = models.UserInfo.objects.create(username="科良", password="123")
#
# models.Blog.objects.create(
# category=1,
# image="xxx/xx.png",
# summary="...",
# title="哈哈",
# text="打卡卡回单卡火炬大厦科技大合计撒",
# creator=v1
# )
# models.Blog.objects.create(
# category=2,
# image="xxx/xx.png",
# summary="...",
# title="嘎嘎",
# text="大神卡大家啊四六级",
# creator=v2
# )
#
# return HttpResponse("成功")
class BlogView(APIView):
authentication_classes = [BlogAuthentication,]
def get(self,request,*args,**kwargs):
"""博客列表"""
# 1.读取数据库中的博客信息
queryset = models.Blog.objects.all().order_by("-id")
# 2.序列化
ser = BlogSerializers(instance=queryset,many=True)
# 3.返回
return Response(ser.data)
def post(self,request):
if not request.user:
return Response({"code": 1002, "error": "认证失败"})
ser = BlogSerializers(data=request.data)
if not ser.is_valid():
return Response({"code": 1003, "error": "校验失败","error":ser.errors})
ser.save(creator=request.user)
return Response({"code": 1000, "data":ser.data})
class BlogDetailView(APIView):
def get(self,request,*args,**kwargs):
"""博客列表"""
pk = kwargs.get("pk")
# 1.根据ID获取对象
instance = models.Blog.objects.filter(id=pk).first()
if not instance:
return Response({"code":1001,"error":"不存在"})
# 2.序列化
ser = BlogDetailSerializers(instance=instance,many=False)
# 3.返回
context = {"code":1000 ,"data":ser.data}
return Response(context)
class CommentSerializers(serializers.ModelSerializer):
class Meta:
model= models.Comment
fields = ["id", "content", "user"]
extra_kwargs = {
"id": {"read_only": True},
"user": {"read_only": True}
}
class CommentView(APIView):
authentication_classes = [BlogAuthentication,]
def get(self,request,blog_id):
"""评论列表"""
# 1.获取博客文章的ID
queryset = models.Comment.objects.filter(blog_id=blog_id)
# 2.序列化
ser = CommentSerializers(instance=queryset, many=True)
# 3.返回
context = {"code": 1000, "data": ser.data}
return Response(context)
def post(self,request,blog_id):
"""发布评论"""
if not request.user:
return Response({"code": 3000,"error": "认证失败"})
blog_object = models.Blog.objects.filter(id=blog_id).first()
print(blog_object,111)
if not blog_object:
return Response({"code": 2000, "error": "博客不存在"})
ser = CommentSerializers(data=request.data)
if not ser.is_valid():
return Response({"code": 1002, "error": "序列化失败","detail": ser.errors})
ser.save(blog=blog_object, user=request.user)
return Response({"code": 1000, "data": ser.data})
class RegisterSerializers(serializers.ModelSerializer):
confirm_password = serializers.CharField(write_only=True)
class Meta:
model=models.UserInfo
fields = ["id", "username", "password", "confirm_password"]
extra_kwargs={
"id": {"read_only": True},
"password": {"write_only": True}
}
def validate_confirm_password(self,value):
password = self.initial_data.get("password")
print("密码",password)
print("重复密码",value)
if password != value:
raise exceptions.ValidationError("密码不一致")
return value
class RegisterView(APIView):
def post(self,request):
# 1.提交数据
# 2.校验
ser = RegisterSerializers(data=request.data)
if ser.is_valid():
ser.validated_data.pop("confirm_password")
ser.save()
return Response({"code": 1000,"data": ser.data})
else:
return Response({"code": 1001, "error": "注册失败", "detail": ser.errors})
class LoginSerializers(serializers.ModelSerializer):
class Meta:
model=models.UserInfo
fields = ["username", "password",]
class LoginView(APIView):
def post(self,request):
# 1.提交数据
# 2.校验
ser = LoginSerializers(data=request.data)
if not ser.is_valid():
return Response({"code": 1001, "error": "校验失败","detail": ser.errors})
instance = models.UserInfo.objects.filter(**ser.validated_data).first()
if not instance:
return Response({"code": 1002, "error": "用户或密码错误"})
token = str(uuid.uuid4())
print(token)
instance.token = token
instance.save()
return Response({"code": 1000,"token": token})
class FavorSerializer(serializers.ModelSerializer):
class Meta:
model = models.Favor
fields = ["blog"]
class FavorView(APIView):
authentication_classes = [BlogAuthentication, Nouthentication]
def post(self,request):
ser = FavorSerializer(data=request.data)
if not ser.is_valid():
return Response({"code": 1002, "data": "校验失败"})
# 存在,不攒
exists = models.Favor.objects.filter(user=request.user, blog =ser.validated_data["blog"])
if exists:
return Response({"code": 1005, "data": "已存在"})
# 不存在 赞
ser.save(user=request.user)
return Response({"code": 1000, "data":ser.data})
评论