作业
from django.db import models
class Car(models.Model):
name = models.CharField(max_length=64)
price = models.DecimalField(max_digits=11, decimal_places=2)
is_delete = models.BooleanField(default=False)
car_brand = models.ForeignKey(to='CarBrand', related_name='cars', db_constraint=False)
sponsors = models.ManyToManyField(to='Sponsor', related_name='cars', db_constraint=False)
@property
def brand(self):
return {
'name': self.car_brand.name,
'country': self.car_brand.country
}
@property
def car_sponsor(self):
sponsor_list = []
sponsors = self.sponsors.all()
for sponsor in sponsors:
sponsor_dic = {
'name': sponsor.name,
}
try:
sponsor_dic['addr'] = sponsor.sponsor_detail.addr
except:
sponsor_dic['addr'] = '无'
sponsor_list.append(sponsor_dic)
return sponsor_list
class CarBrand(models.Model):
name = models.CharField(max_length=64)
country = models.CharField(max_length=64)
class Sponsor(models.Model):
name = models.CharField(max_length=64)
sponsor_detail = models.OneToOneField(to='SponsorDetail', related_name='sponsor', db_constraint=False)
class SponsorDetail(models.Model):
addr = models.CharField(max_length=64)
# exception.py
from rest_framework.response import Response
from rest_framework.views import exception_handler as drf_exception_handler
def exception_handler(exc,content):
response = drf_exception_handler(exc,content)
detail = f'{content.get("view").__class__}-{content.get("request").method}-{exc}'
if not response:
response = Response({'detail':detail},status=500)
else:
response.data={'detail':detail}
import sys
sys.stderr.write(f'异常:{response.data.get("detail")}')
return response
# serializer.py
from rest_framework import serializers
from api import models
class CarModelSerializer(serializers.ModelSerializer):
class Meta:
model = models.Car
fields = ['name','price','car_brand','sponsors','brand','car_sponsor']
extra_kwargs = {
'car_brand':{'write_only':True},
'sponsors':{'write_only':True}
}
# views.py
from rest_framework.response import Response
from api import models
from rest_framework.views import APIView
from api.serializer import CarModelSerializer
class CarAPIView(APIView):
def get(self, request, *args, **kwargs):
pk = kwargs.get('pk')
if pk:
car_obj = models.Car.objects.filter(pk=pk, is_delete=False).first()
car_ser = CarModelSerializer(car_obj)
else:
car_query = models.Car.objects.filter(is_delete=False).all()
print(car_query)
car_ser = CarModelSerializer(car_query, many=True)
return Response(data={
'status': 0,
'msg': 'ok',
'results': car_ser.data
})
def post(self, request, *args, **kwargs):
if isinstance(request.data, dict):
many = False
elif isinstance(request.data, list):
many = True
else:
return Response(data={'detail': '数据有误'}, status=400)
car_ser = CarModelSerializer(data=request.data, many=many)
car_ser.is_valid(raise_exception=True)
car_obj_or_list = car_ser.save()
return Response(data={
'status': 0,
'msg': 'ok',
'results': car_obj_or_list.data
})
def patch(self, request, *args, **kwargs):
pk = kwargs.get('pk')
if pk:
try:
car_instance = models.Car.objects.get(pk=pk, is_delete=False)
except:
return Response(data={
'status': 2,
'msg': '数据错误'
})
many = False
else:
try:
pks = []
for dic in request.data:
pk = dic.pop('pk')
pks.append(pk)
car_instance = models.Car.objects.filter(is_delete=False, pk__in=pks).all()
if len(pks) != len(car_instance):
raise Exception('pk对应数据不存在')
except Exception as e:
return Response({'detail': f"{e}"})
many = True
car_ser = CarModelSerializer(instance=car_instance, data=request.data, partial=True, many=many)
car_ser.is_valid(raise_exception=True)
car_obj = car_ser.save()
return Response(data={
'status': 0,
'msg': 'ok',
'results': CarModelSerializer(car_obj).data
})
def delete(self, request, *args, **kwargs):
pk = kwargs.get('pk')
if pk:
pks = pk
else:
pks = request.data
try:
rows = models.Car.objects.filter(is_delete=False, pk__in=pks).update(is_delete=True)
except:
return Response({'status': 1, 'msg': '数据有误'})
if rows:
return Response({'status': 0, 'msg': '删除成功'})