models.py
from django.db import models
# Create your models here.
# 基表
class BaseModel(models.Model):
is_delete = models.BooleanField(default=False)
create_time = models.DateTimeField(auto_now_add=True, null=True)
# abstract = true 表示基表为抽象表,不会完成数据库迁移
class Meta:
abstract = True
class Book(BaseModel):
name = models.CharField(max_length=32)
price = models.DecimalField(max_digits=5, decimal_places=2)
img = models.ImageField(upload_to='img', default='img/default.png')
publish = models.ForeignKey(to='Publish', db_constraint=False,
on_delete=models.DO_NOTHING, null=True)
authors = models.ManyToManyField(to='Auth', db_constraint=False, null=True)
class Meta:
db_table = 'book'
verbose_name = '书籍'
verbose_name_plural = verbose_name
def __str__(self):
return self.name
@property
def publish_name(self):
return self.publish.name
@property
def authors_info(self):
authors_list =[]
for author in self.authors.all():
authors_list.append(
{'name':author.name,
'age':author.age,
'mobile':author.detail.mobile
}
)
return authors_list
class Publish(BaseModel):
name = models.CharField(max_length=32)
addr = models.CharField(max_length=64)
class Meta:
db_table = 'publish'
verbose_name = '出版社'
verbose_name_plural = verbose_name
def __str__(self):
return self.name
class Auth(BaseModel):
name = models.CharField(max_length=32)
age = models.IntegerField()
class Meta:
db_table = 'auth'
verbose_name = '作者'
verbose_name_plural = verbose_name
def __str__(self):
return self.name
class AuthDetail(BaseModel):
mobile = models.CharField(max_length=11)
author = models.OneToOneField(to='Auth',
db_constraint=False,
on_delete=models.CASCADE,
null=True,
related_name='detail')
class Meta:
db_table = 'auth_detail'
verbose_name = '作者详情'
verbose_name_plural = verbose_name
class User(models.Model):
SEX_CHOICE = [
(0, '男'),
(1, '女'),
(2, '未知')
]
username = models.CharField(max_length=32)
pwd = models.CharField(max_length=32)
sex = models.IntegerField(choices=SEX_CHOICE, default=0)
icon = models.ImageField(upload_to='icon', default='/icon/default.png')
class Meta:
db_table = 'user'
verbose_name = '用户'
verbose_name_plural = verbose_name
def __str__(self):
return self.username
序列化类
from rest_framework import serializers
from django.conf import settings
from api import models
# class UserSerializer(serializers.Serializer):
# username = serializers.CharField()
# # pwd = serializers.CharField()
# sex = serializers.IntegerField()
# icon = serializers.ImageField()
class UserV2Serializer(serializers.Serializer):
username = serializers.CharField(min_length=4,
max_length=8,
error_messages={
'min_length': '用户名最少4位!',
'max_length': '用户名最长8位!'
}
)
pwd = serializers.CharField(write_only=True,
min_length=6,
max_length=10,
error_messages={
'min_length': '密码最少6位!',
'max_length': '密码最长10位!'
})
re_pwd = serializers.CharField(min_length=6,
max_length=10,
write_only=True,
required=True,
error_messages={
'min_length': '密码最少6位!',
'max_length': '密码最长10位!',
'required': '必须确认密码!'
}
)
sex = serializers.IntegerField(write_only=True, required=False)
gender = serializers.SerializerMethodField(read_only=True)
def get_gender(self, user_obj):
return user_obj.get_sex_display()
icon = serializers.SerializerMethodField(read_only=True)
def get_icon(self, user_obj):
icon_url = 'http://127.0.0.1:8000{}{}'.format(settings.MEDIA_URL, user_obj.icon)
return icon_url
#局部校验
def validate_username(self, value):
if 'sb' in value:
raise serializers.ValidationError('用户名包含敏感词汇!')
return value
def validate(self, attrs):
pwd = attrs.get('pwd')
re_pwd = attrs.get('re_pwd')
if pwd:
if re_pwd:
attrs.pop('re_pwd')
if pwd != re_pwd:
raise serializers.ValidationError('两次密码不一致!')
else:
raise serializers.ValidationError('必须确认密码!')
return attrs
# 继承serializers.Serializer增加数据需要重写create方法,继承ModelSerializer不需要
def create(self, validated_data):
try:
return models.User.objects.create(**validated_data)
except:
raise IOError('数据入库失败!')
class BookModelSerializer(serializers.ModelSerializer):
class Meta:
model = models.Book
fields = ('name', 'price', 'publish_name', 'authors_info') # 表示只参与序列化的字段
# exclude = ('id',) # 表示不参与序列化的字段
# 序列化与反序列化整合
class BookModelSerializerV2(serializers.ModelSerializer):
class Meta:
model = models.Book
fields = ('name', 'price', 'publish', 'authors', 'img', 'publish_name', 'authors_info')
extra_kwargs = {
'publish': {
'required': True,
'write_only': True,
'error_messages': {
'required': 'publish必填!'
}
},
'authors': {
'required': True,
'write_only': True,
'error_messages': {
'required': 'authors必填!'
}
},
'img': {
'read_only': True
}
}
#局部校验
def validate_name(self, value):
if 'sb' in value:
raise serializers.ValidationError('书名包含敏感词汇!')
return value
# 全局校验
def validate(self, attrs):
name = attrs.get('name')
publish = attrs.get('publish')
if models.Book.objects.filter(name=name, publish=publish):
raise serializers.ValidationError('书籍已经存在!')
return attrs
urls.py
from django.urls import path, re_path
from . import views
urlpatterns = [
# path('admin/', admin.site.urls),
# path('books/', views.BookView.as_view()),
# re_path('books/(?P<pk>.*)/', views.BookView.as_view()),
path('users/', views.UserAPIView.as_view()),
re_path('users/(?P<pk>.*)/', views.UserAPIView.as_view()),
path('books/', views.BookModelAPIView.as_view()),
re_path('books/(?P<pk>.*)/', views.BookModelAPIView.as_view()),
# path('test/', views.my_view),
]
views.py
from django.shortcuts import render,HttpResponse
from django.http import JsonResponse
from django.views import View
from . import models, myserializers
from rest_framework.views import APIView
from rest_framework.response import Response
# Create your views here.
class BookView(View):
def get(self, request, *args, **kwargs):
pk = kwargs.get('pk')
if pk:
book_info_list = models.Book.objects.filter(pk=pk).values('name', 'price')
if not book_info_list:
return JsonResponse({
'status': 2,
'msg': '书籍不存在!'
})
return JsonResponse({
'status': 1,
'msg': 'ok',
'result': book_info_list[0]
})
book_info_list = models.Book.objects.values('id', 'name', 'price')
if not book_info_list:
return JsonResponse({
'status': 2,
'msg': '没有数据!'
})
return JsonResponse({
'status': 1,
'msg': 'ok',
'result': list(book_info_list)
})
# return JsonResponse({})
class UserAPIView(APIView):
def get(self, request, *args, **kwargs):
user_query = models.User.objects.all()
user_ser = myserializers.UserV2Serializer(user_query, many=True)
# print(user_ser.data)
return Response(data=user_ser.data)
def post(self, request):
request_data = request.data
user_ser = myserializers.UserV2Serializer(data=request_data)
if user_ser.is_valid():
user_obj = user_ser.save()
re_data = myserializers.UserV2Serializer(user_obj).data
return Response(data=re_data)
else:
return Response(status=201,data=user_ser.errors)
class BookModelAPIView(APIView):
def get(self, request, *args, **kwargs):
pk = kwargs.get('pk')
print(pk)
if pk:
book_obj = models.Book.objects.filter(is_delete=False, pk=pk).first()
if not book_obj:
return Response('书籍不存在!')
book_ser = myserializers.BookModelSerializerV2(book_obj)
return Response(data=book_ser.data)
book_query = models.Book.objects.filter(is_delete=False)
book_ser = myserializers.BookModelSerializerV2(book_query, many=True)
return Response(data=book_ser.data)
def post(self, request, *args, **kwargs):
request_data = request.data
book_ser = myserializers.BookModelSerializerV2(data=request_data)
if book_ser.is_valid():
book_obj = book_ser.save()
res_data = myserializers.BookModelSerializerV2(book_obj).data
return Response(data=res_data)
else:
return Response(data=book_ser.errors)
def delete(self, request, *args, **kwargs):
# 有名分组传参在kwargs中获取
pk = kwargs.get('pk')
print(pk)
if pk:
pks = [pk]
else:
pks = request.data.get('pks')
if not pks:
return Response('删除失败!')
print(pks)
book_query = models.Book.objects.filter(is_delete=False, pk__in=pks)
res = book_query.update(is_delete=True)
if not res:
return Response('删除失败!')
return Response('删除成功!')