创建项目的步骤

  • 首先创建一个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})