books一系列接口

drf数据的增删改查

模型类

from django.db import models


class BaseModel(models.Model):
    is_delete = models.BooleanField(default=False)
    # auto_now_add创建的时候,不需要手动插入时间,自动插入当前时间
    create_time = models.DateTimeField(auto_now_add=True)
    # auto_now,只要更新,就会把当前时间插入
    last_update_time = models.DateTimeField(auto_now=True)

    # import datetime
    # create_time = models.DateTimeField(default=datetime.datetime.now)

    class Meta:
        # 单个字段有索引,有唯一  db_index  unique
        # 联合起来,多个字段,有联合索引,联合唯一,,,index_together,unique_together

        abstract = True  # 抽象表,不再数据库中建立表


# Create your models here.
class Book(BaseModel):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32, verbose_name='书名', help_text='这里填写书名')
    price = models.DecimalField(max_digits=8, decimal_places=2, verbose_name='价格', help_text='这里填写书的价格')
    # to_field 默认不写,关联到Publish主键
    # db_constraint=False,逻辑上的关联,实质上并没有外键联系,增删不会受外键影响,但是orm查询不影响
    publish = models.ForeignKey(to='Publish', on_delete=models.DO_NOTHING, db_constraint=False)

    # 社么时候用自动,什么时候用手动?
    # 第三张表只有关联字段,用自动,,第三张表有扩展字段,需要手动写,
    authors = models.ManyToManyField(to='Author', db_constraint=False)

    class Meta:
        verbose_name_plural = '书表'  # admin中表名的显示

    def __str__(self):
        return self.name

    @property
    def publish_name(self):
        return self.publish.name

    def author_list(self):
        authors_list=self.authors.all()
        # ll=[]
        # for author in authors_list:
        #     ll.append({'name': author.name,'sex':author.get_sex_display()})
        # # return ll
        return [{'name': author.name,'sex':author.get_sex_display()} for author in authors_list]




class Publish(models.Model):
    name = models.CharField(max_length=32)
    addr = models.CharField(max_length=64)

    class Meta:
        verbose_name_plural = '出版社表'

    def __str__(self):
        return self.name


class Author(BaseModel):
    name = models.CharField(max_length=32)
    sex = models.IntegerField(choices=((1, '男'), (2, '女')))
    author_detail = models.OneToOneField(to='AuthorDetail', db_constraint=False, on_delete=models.CASCADE)

    class Meta:
        verbose_name_plural = '作者表'


class AuthorDetail(BaseModel):
    mobile = models.CharField(max_length=11)

    class Meta:
        verbose_name_plural = '作者详情表'

    def __str__(self):
        return self.mobile

# models.CASCADE
# models.SET_DEFAULT
# models.SET_NULL
# models.DO_NOTHING
# 表断关联
# 1.表之间没有外键关联,但是有哦外键逻辑关联,(有充当外键的字段)
# 2.断关联后不会影响数据库查询效率,但是会极大提高数据库增删改效率,(不影响增删改查操作)
# 3.断关联一定要通过逻辑保证表之间数据的安全,不要出现脏数据,代码控制
# 4.断关联
# 5.级联关系:
# 作者没了,详情也没了,on_delete=models.CASCADE
# 出版社没了,书还是那个出版社出版 :on_delete=models.DO_NOTHING
# 部门没了,员工没有部门(空不能):null=True,on_delete=models.SER_NULL
# 部门没了,员工进入默认部门(默认值):default=0,on_delete=models.SET_DEFAULT

写完后在admin.py中注册

from app01 import models

admin.site.register(models.Book)
admin.site.register(models.Author)
admin.site.register(models.AuthorDetail)
admin.site.register(models.Publish)

序列化类

# -*- coding: UTF-8 -*- 
# @Date :2022/12/10 16:42
from rest_framework import serializers
from app01.models import Book


class BookListSerializer(serializers.ListSerializer):
    # def create(self, validated_data):
    #     print(validated_data)
    # super().__init__(validated_data)

    def update(self, instance, validated_data):
        print(validated_data)
        # 报错数据
        return [
            self.child.update(instance[i], attrs) for i, attrs in enumerate(validated_data)
        ]


class BookModelSerializer(serializers.ModelSerializer):
    # 如果序列化的是数据库的表,尽量使用ModelsSerializer
    # 第一种方案(序列化可以,反序列化有问题
    # publish = serializers.CharField(source='publish.name')

    # 第二中方案 ,models中写方法
    class Meta:
        list_serializer_class = BookListSerializer
        model = Book
        # fields = '__all__'
        # depth = 1
        fields = ('id','name', 'price', 'authors', 'publish', 'publish_name', 'author_list')
        extra_kwargs = {
            'publish': {'write_only': True},
            'publish_name': {'read_only': True},
            'authors': {'write_only': True},
            'author_list': {'read_only': True},
        }

路由配置

#urls.py
path('books/', views.BookAPIView.as_view()),
re_path('books/(?P<pk>\d+)', views.BookAPIView.as_view()),

视图类

#views.py

from rest_framework.views import APIView
from app01.models import Book
from app01.serialize import BookModelSerializer
from rest_framework.response import Response


class BookAPIView(APIView):
    def get(self, request, *args, **kwargs):
        # 查单个和查所有合并到一起
        # 查单条数据
        if kwargs:
            pk = kwargs.get('pk')
            book_obj = Book.objects.filter(pk=pk).first()
            book_ser = BookModelSerializer(book_obj)
            return Response(data=book_ser.data)
        # 查所有数据
        book_list = Book.objects.all().filter(is_delete=False)
        book_list_ser = BookModelSerializer(book_list, many=True)
        return Response(data=book_list_ser.data)

    def post(self, request, *args, **kwargs):
        # 具备增单条,和增多条的功能
        if isinstance(request.data, dict):
            book_ser = BookModelSerializer(data=request.data)
            book_ser.is_valid(raise_exception=True)
            book_ser.save()
            return Response(data=book_ser.data)
        elif isinstance(request.data, list):
            # 此时的book_ser是Listserializer对象
            book_ser = BookModelSerializer(data=request.data, many=True)  # 增多条
            book_ser.is_valid(raise_exception=True)
            book_ser.save()  # 调用的是Listserializer的save方法
            # 新增,会掉create方法,Listserializer的create方法
            return Response(data=book_ser.data)

    def put(self, request, *args, **kwargs):
        # 改一个
        if kwargs.get('pk', None):
            book_obj = Book.objects.filter(pk=kwargs).first()
            book_ser = BookModelSerializer(instance=book_obj, data=request.data, partial=True)
            book_ser.is_valid(raise_exception=True)
            book_ser.save()
            return Response(data=book_ser.data)
        else:
            book_list = []
            modify_data = []

            for item in request.data:
                pk = item.pop('id')
                book_obj = Book.objects.get(pk=pk)
                book_list.append(book_obj)
                modify_data.append(item)

            # for i,is_data in enumerate(modify_data):
            #     book_ser = BookModelSerializer(instance=book_list[i], data=is_data, many=True)
            #     book_ser.save()
            # return Response(book_ser.data)

            book_ser = BookModelSerializer(instance=book_list, data=modify_data, many=True)
            book_ser.is_valid(raise_exception=True)
            book_ser.save()
            return Response(book_ser.data)

    def delete(self, request, *args, **kwargs):
        # 单个删除,
        # 批量删除
        pk = kwargs.get('pk')
        pks = []
        if pk:
            pks.append(pk)
            # 不管单条删除还是多条删除都用多条删除
        else:
            pks = request.data.get('pks')
        # 把is_delete设置成True
        # ret返回受影响的行数
        ret = Book.objects.filter(pk__in=pks, is_delete=False).update(is_delete=True)
        if ret:
            return Response(data={'msg': '删除成功'})
        else:
            return Response(data={'msg': '没有要删除的数据'})
posted @ 2022-12-12 17:34  ExpiredSaury  阅读(26)  评论(0编辑  收藏  举报