Django---drf, books系列表接口、分页器、根据ip进行频率限制---作业
1 一个表可不可以有多个自增字段
每个表只能有一个自增字段,否则数据库迁移命令报错
AssertionError: Model app01.ABC can't have more than one AutoField.
2 用GenericAPIView重写book的单增,群增,
view.py
from django.shortcuts import render
from rest_framework.generics import GenericAPIView
from rest_framework.response import Response
from app01.models import Book
from app01.ser import BookSerializer
# Create your views here.
class BookView(GenericAPIView):
# .filter(is_delete=False)筛选一下,不然删除的数据也出来了
queryset = Book.objects.all().filter(is_delete=False)
serializer_class = BookSerializer
def get(self, request, *args, **kwargs):
if not kwargs:
book_list = self.get_queryset()
book_ser = self.get_serializer(book_list, many=True)
return Response(data=book_ser.data)
else:
book = self.get_object() #有pk获取单个对象
# book = Book.objects.filter(pk=kwargs.get('pk', None)).first()
book_ser = self.get_serializer(book)
return Response(book_ser.data)
def post(self, request, *args, **kwargs):
#增单条
if isinstance(request.data, dict):#isinstance判断request.data是dict就执行
book_ser = self.get_serializer(data=request.data)
book_ser.is_valid(raise_exception=True)
book_ser.save()
return Response(data=book_ser.data)
#增多条
elif isinstance(request.data, list):#isinstance判断request.data是list就执行
book_ser = BookSerializer(data=request.data, many=True)
book_ser.is_valid(raise_exception=True)
#调用的from rest_framework.serializers import ListSerializer的save方法,而不是BookSerializer的
book_ser.save()
return Response(data=book_ser.data)
models.py
from django.db import models
from django.contrib.auth.models import AbstractUser
# Create your models here.
class BaseModel(models.Model):
is_delete = models.BooleanField(default=False)
create_time = models.DateTimeField(auto_now_add=True)#创建数据时,当前时间更新到该字段
last_update_time = models.DateTimeField(auto_now=True)#数据更新时,当前时间更新到该字段
class Meta:
#abstract表示抽象表,不在数据库建立出来
abstract = True
class Book(BaseModel):
name = models.CharField(max_length=64, verbose_name='书籍名称', help_text='该字段添加书籍名称')
price = models.DecimalField(max_digits=6, decimal_places=2)
authors = models.ManyToManyField(to='Author', db_constraint=False)
#db_constraint逻辑上的关联,实质上没有外键关系,增删不受影响,orm也不受影响
publish = models.ForeignKey(to='Publish', on_delete=models.DO_NOTHING, 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):
author_list = self.authors.all()
#get_sex_display获取choices的显示值
#字典推导式
return [{'name': author.name, 'sex': author.get_sex_display()}for author in author_list]
class Author(BaseModel):
name = models.CharField(max_length=64)
sex = models.IntegerField(choices=((1, '男'), (2, '女')))
# db_constraint逻辑上的关联,实质上没有外键关系,增删不受影响,orm也不受影响
authordetail = models.OneToOneField(to='AuthorDetail', on_delete=models.CASCADE, db_constraint=False)
class Meta:
verbose_name_plural = '作者表'
def __str__(self):
return self.name
class AuthorDetail(BaseModel):
mobile = models.CharField(max_length=11, verbose_name='手机号')
class Meta:
verbose_name_plural = '作者详情表'
class Publish(BaseModel):
name = models.CharField(max_length=64)
addr = models.CharField(max_length=64)
def __str__(self):
return self.name
class Meta:
verbose_name_plural = '出版社表'
ser.py<序列化类>
from rest_framework import serializers
from app01.models import Book
class BookSerializer(serializers.ModelSerializer):
class Meta:
model = Book
# fields = '__all__'
#想要序列化的字段
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},
}
总路由、分发给app01的子路由
from django.contrib import admin
from django.urls import path, include #路由分发
urlpatterns = [
path('admin/', admin.site.urls),
path('app01/', include('app01.urls')),
]
app01的子路由
from django.urls import path, re_path
from app01 import views
urlpatterns = [
path('books/', views.BookView.as_view()),
re_path('books/(?P<pk>\d+)', views.BookView.as_view())
]
在admin.py注册方便在admin页面添加书籍数据
from django.contrib import admin
# Register your models here.
from app01 import models
admin.site.register(models.Book)
admin.site.register(models.Author)
admin.site.register(models.AuthorDetail)
admin.site.register(models.Publish)