| |
| |
| class PublishModelSerializer(serializers.ModelSerializer): |
| |
| re_name = serializers.CharField(write_only=True) |
| class Meta: |
| model = models.Publish |
| fields = ('name', 're_name', 'address') |
| def validate(self, attrs): |
| name = attrs.get('name') |
| re_name = attrs.pop('re_name') |
| if name != re_name: |
| raise serializers.ValidationError({'re_name': '确认名字有误'}) |
| return attrs |
| |
| class Book(BaseModel): |
| |
| @property |
| def publish_detail(self): |
| from . import serializers |
| data = serializers.PublishModelSerializer(self.publish).data |
| return data |
| from django.conf.urls import url |
| from . import views |
| urlpatterns = [ |
| |
| url(r'^v3/books/$', views.BookV3APIView.as_view()), |
| url(r'^v3/books/(?P<pk>.*)/$', views.BookV3APIView.as_view()), |
| ] |
| |
| from django.db import models |
| from utils.model import BaseModel |
| class Book(BaseModel): |
| name = models.CharField(max_length=64) |
| price = models.DecimalField(max_digits=5, decimal_places=2) |
| img = models.ImageField(upload_to='img', default='img/default.png') |
| publish = models.ForeignKey(to='Publish', null=True, |
| related_name='books', |
| db_constraint=False, |
| on_delete=models.DO_NOTHING, |
| ) |
| authors = models.ManyToManyField(to='Author', null=True, |
| related_name='books', |
| db_constraint=False, |
| ) |
| |
| @property |
| def publish_name(self): |
| return self.publish.name |
| |
| @property |
| def authors_info(self): |
| author_list = [] |
| for author in self.authors.all(): |
| author_list.append({ |
| 'name': author.name, |
| 'age': author.age, |
| 'mobile': author.detail.mobile |
| }) |
| return author_list |
| |
| @property |
| def publish_bac(self): |
| from . import serializers |
| data = serializers.PublishModelSerializer(self.publish).data |
| return data |
| |
| class Meta: |
| db_table = 'old_boy_book' |
| verbose_name = '书籍' |
| verbose_name_plural = verbose_name |
| |
| |
| |
| def __str__(self): |
| return self.name |
| |
| class Publish(BaseModel): |
| name = models.CharField(max_length=64) |
| address = models.CharField(max_length=64) |
| |
| class Meta: |
| db_table = 'old_boy_publish' |
| verbose_name = '出版社' |
| verbose_name_plural = verbose_name |
| |
| def __str__(self): |
| return self.name |
| |
| class Author(BaseModel): |
| name = models.CharField(max_length=64) |
| age = models.IntegerField() |
| |
| @property |
| def mobile(self): |
| return self.detail.mobile |
| |
| class Meta: |
| db_table = 'old_boy_author' |
| verbose_name = '作者' |
| verbose_name_plural = verbose_name |
| |
| def __str__(self): |
| return self.name |
| |
| class AuthorDetail(BaseModel): |
| mobile = models.CharField(max_length=11) |
| |
| author = models.OneToOneField(to='Author', null=True, |
| related_name='detail', |
| db_constraint=False, |
| on_delete=models.CASCADE |
| ) |
| |
| class Meta: |
| db_table = 'old_boy_author_detail' |
| verbose_name = '作者详情' |
| verbose_name_plural = verbose_name |
| |
| def __str__(self): |
| return '%s的详情' % self.author.name |
| |
| |
| |
| |
| |
| class BookV3ListSerializer(serializers.ListSerializer): |
| def update(self, instance, validated_data): |
| ''' |
| :param instance: [book_obj1, ..., book_obj2] |
| :param validated_data: [{更新数据的字段}, ..., {更新数据的字段}] |
| :return: [book_new_obj1, ..., book_new_obj2] |
| ''' |
| for index, obj in enumerate(instance): |
| |
| for attr, value in validated_data[index].items(): |
| |
| if hasattr(obj, attr): |
| setattr(obj, attr, value) |
| |
| obj.save() |
| return instance |
| |
| class BookV3ModelSerializer(serializers.ModelSerializer): |
| class Meta: |
| model = models.Book |
| fields = ('name', 'price', 'publish', 'authors', 'img', 'publish_name', 'authors_info') |
| list_serializer_class = BookV3ListSerializer |
| extra_kwargs = { |
| 'publish': { |
| 'required': True, |
| 'write_only': True |
| }, |
| 'authors': { |
| 'required': True, |
| 'write_only': True |
| }, |
| '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({'book': '书籍以存在'}) |
| return attrs |
| class BookV3APIView(APIView): |
| |
| def get(self, request, *args, **kwargs): |
| pk = kwargs.get('pk') |
| if pk: |
| book_obj = models.Book.objects.filter(is_delete=False, pk=pk).first() |
| if not book_obj: |
| return APIResponse(1, 'pk error') |
| book_ser = serializers.BookV3ModelSerializer(book_obj) |
| return APIResponse(0, 'ok', results=book_ser.data) |
| book_query = models.Book.objects.filter(is_delete=False).all().order_by('-id') |
| book_ser = serializers.BookV3ModelSerializer(book_query, many=True) |
| return APIResponse(0, 'ok', results=book_ser.data) |
| |
| |
| def post(self, request, *args, **kwargs): |
| |
| |
| request_data = request.data |
| if isinstance(request_data, dict): |
| data = [request_data, ] |
| elif isinstance(request_data, list): |
| data = request_data |
| else: |
| return APIResponse(1, '数据格式有误') |
| book_ser = serializers.BookV3ModelSerializer(data=data, many=True) |
| if book_ser.is_valid(): |
| book_obj_list = book_ser.save() |
| return APIResponse(0, 'ok', |
| results=serializers.BookV3ModelSerializer(book_obj_list, many=True).data |
| ) |
| else: |
| return APIResponse(1, '添加失败', results=book_ser.errors) |
| |
| """ |
| 1)先确定要更新的对象 主键们 与 数据们 |
| 2)通过校验数据库剔除 已删除的对象 与 不存在的对象 |
| 主键们 => 剔除过程 => 可以修改的对象们 |
| 数据们 => 剔除过程 => 可以修改的对象们对应的数据们 |
| 3)反序列化及校验过程 |
| 通过 => save() 完成更新 |
| 失败 => ser_obj.errors 返回 |
| """ |
| |
| def patch(self, request, *args, **kwargs): |
| |
| |
| |
| |
| |
| |
| |
| pk = kwargs.get('pk') |
| request_data = request.data |
| if pk: |
| if not isinstance(request_data, dict): |
| return APIResponse(1, '单改数据有误') |
| pks = [pk, ] |
| data = [request_data, ] |
| elif isinstance(request_data, list): |
| try: |
| pks = [] |
| for dic in request_data: |
| pks.append(dic.pop('pk')) |
| data = request_data |
| except: |
| return APIResponse(1, '群改数据有误') |
| else: |
| return APIResponse(1, '数据格式有误') |
| |
| |
| book_query = [] |
| filter_data = [] |
| for index, pk in enumerate(pks): |
| book_obj = models.Book.objects.filter(is_delete=False, pk=pk).first() |
| if book_obj: |
| book_query.append(book_obj) |
| filter_data.append(data[index]) |
| |
| book_ser = serializers.BookV3ModelSerializer(instance=book_query, data=filter_data, many=True, partial=True) |
| if book_ser.is_valid(): |
| book_obj_list = book_ser.save() |
| return APIResponse(1, 'ok', |
| results=serializers.BookV3ModelSerializer(book_obj_list, many=True).data |
| ) |
| else: |
| return APIResponse(1, '更新失败', results=book_ser.errors) |
| |
| |
| def delete(self, request, *args, **kwargs): |
| |
| |
| pk = kwargs.get('pk') |
| if pk: |
| pks = [pk] |
| else: |
| pks = request.data.get('pks') |
| if not pks: |
| return APIResponse(1, '删除失败') |
| book_query = models.Book.objects.filter(is_delete=False, pk__in=pks) |
| if not book_query.update(is_delete=True): |
| return APIResponse(1, '删除失败') |
| return APIResponse(0, '删除成功') |