drf - ModelSerializers 직렬 화
목차
*****
drf - ModelSerializers 직렬 화
프로젝트 준비
settings. py 설정
# rest_framework app
INSTALLED_APPS = [
# ...
'rest_framework',
]
# mysql
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'dg_proj',
'USER': 'root',
'PASSWORD': '123',
'HOST': '127.0.0.1',
'PORT': 3306
}
}
# pymysql
"""
__init__
import pymysql
pymysql.install_as_MySQLdb()
"""
#
LANGUAGE_CODE = 'zh-hans'
TIME_ZONE = 'Asia/Shanghai'
USE_I18N = True
USE_L10N = True
USE_TZ = False
#
STATIC_URL = '/static/'
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'static'),
)
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
경로
주 경로 urls. py
from django.conf.urls import url, include
from django.contib import admin
from django.views import serve
from django.conf import settings
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^api/', include('api.urls')),
url(r'^media/(?P.*)', serve, {'document_root': settings.MEDIA_ROOT}),
]
하위 경로 api / urls. py
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^books/$', views.BookAPIView.as_view()),
url(r'^books/(?P\d+)/$', views.BookAPIView.as_view()),
]
멀 티 탭 디자인
표 관계 분석
"""
Book :
name, price, img, publish( Publish ), authors( Author ), is_delete, create_time
Publish :
name, address, is_delete, create_time
Author :
name, age, is_delete, create_time
AuthorDetail :
mobile, author( Author ), is_delete, create_time
is_delete, create_time , ,
BaseModel :
is_delete, create_time
"""
표 관계 도:
모델 생 성
기본 표 utils / models. py
from django.db import models
class BaseModel(models.Model):
is_delete = models.BooleanField(default=False)
create_time = models.DateTimeField(auto_now_add=True, null=True)
class Meta:
# ,
abstract = True
모형 층 api / models. py
from django.db import models
from utils.models import BaseModel
"""
relate_name: , relate_name , ( _set)
db_constraint: False
on_delete: CASCSADE,
DO_NOTHING, ,
SET_NULL, , null, null True
SET_DEFAULT, , , default
: on_delete , ,
db_table: ,
verbose_name: admin ,
"""
# Create your models here.
class Book(BaseModel):
name = models.CharField(max_length=64)
price = models.DecimalField(max_digits=6, decimal_places=2)
img = models.ImageField(upload_to='icon', default='icon/default.png')
publish = models.ForeignKey(to='Publish',
null=True,
related_name='books',
db_constraint=False,
on_delete=models.DO_NOTHING
# on_delete=models.SET_NULL, null=True
# on_delete=models.SET_DEFAULT, default=1
)
authors = models.ManyToManyField(to='Author',
related_name='authors',
db_constraint=False
)
# model , , read_only
@property
def publish_info(self):
return {'name': self.publish.name, 'address': self.publish.address}
@property
def author_info(self):
author_list = []
for author in self.authors.all():
detail = AuthorDetail.objects.filter(author_id=self.author.id)
author_list.append({
'name': author.name,
'age': author.age,
# : author.detail ,
# 'mobile': author.detail.mobile
'mobile': ' ' if not detail else author.detail.mobile
})
return author_list
class Meta:
db_table = "books"
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 = '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 = 'detail'
verbose_name = ' '
verbose_name_plural = verbose_name
def __str__(self):
return f"{self.author.name} "
class Publish(BaseModel):
name = models.CharField(max_length=64)
address = models.CharField(max_length=128)
class Meta:
db_table = 'publish'
verbose_name = ' '
verbose_name_plural = verbose_name
def __str__(self):
return self.name
모델 직렬 화
계승
rest_framework.serializers
중 ModelSerializer
eg:publish = PublishModelSerializer()
from rest_framework import serializers
from . import models
#
class PublishModelSerializer(serializers.ModelSerializer):
class Meta:
model = models.Publish
fields = ('name', 'address')
#
class AuthorModelSerializer(serializers.ModelSerializer):
class Meta:
model = models.Author
fields = ('name', 'age', 'mobile')
class BookModelSerializer(serializers.ModelSerializer):
#
publish = PublishModelSerializer()
authors = AuthorModelSerializer(many=True)
""" :
ModelSerializer , fields
p_n = serializers.SerializerMethodField()
def get_p_n(self, obj: models.Book):
return obj.publish.name
"""
class Meta:
#
model = models.Book
#
fields = ('name', 'price', 'img', 'publish', 'authors', 'publish_info', 'author_info')
""" :
fields = "__all__" :
exclude = ('id', 'is_delete'): ,
depth = 1 : ( )
"""
보기에 서 api / views. py 사용 하기
from rest_framework.views import APIView
from utils.response import APIResponse
from . import models, serializers
class BookAPIView(APIView):
def get(self, request, *args, **kwargs):
#
pk = kwargs.get('pk')
if pk:
book_obj = models.Book.objects.filter(pk=pk, is_delete=False).first()
if not book_obj:
return APIResponse(1, 'pk ')
book_ser = serializers.BookModelSerializer(book_obj)
return APIResponse(0, 'ok', results=book_ser.data)
book_obj_list = models.Book.objects.filter(is_delete=False).all()
if not book_obj_list:
return APIResponse(1,' ')
book_ser = serializers.BookModelSerializer(book_obj_list, many=True)
return APIResponse(0,'ok',results=book_ser.data)
모델 역 직렬 화
계승
rest_framework.serializers
중 ModelSerializer
from rest_framework import serializers
from . import models
class BookModelDeserializer(serializers.ModelSerializer):
# , fields
re_name = serializers.CharField(
min_length=3,
required=True,
error_messages={
'min_length': ' ',
'required': ' '
}
)
class Meta:
model = models.Book
fields = ('name', 're_name', 'price', 'publish', 'authors')
extra_kwargs = {
'name':{
'min_length': 3,
'error_messages': {
'min_length': ' ',
'required': ' '
}
},
# required False,
'publish':{
'required': True,
'error_messages':{
'required': ' '
}
},
'authors':{
'required': True,
'error_messages':{
'required': ' '
}
}
}
#
#
def validate_name(self, value):
if 'sb' in value:
raise serializers.ValidationError(' ')
return value
def validate(self, attr):
name = attr.get('name')
re_name = attr.get('re_name')
publish = attr.get('publish')
if name != re_name:
raise serializers.ValidationError(
{'re_name': ' '}
)
if models.Book.objects.filter(name=name, publish=publish):
raise serializers.ValidationError(
{'book': ' '}
)
return attr
보기에 서 api / views. py 사용 하기
from rest_framework.views import APIView
from utils.response import APIResponse
from . import models, serializers
class BookAPIView(APIView):
def post(self, request, *args, **kwargs):
book_ser = serializers.BookModelDeserializer(data=request.data)
if book_ser.is_valid():
book_obj = book_ser.save()
results = serializers.BookModelDeserializer(book_obj).data
return APIResponse(0, 'ok', results=results)
else:
return APIResponse(1, ' ', resultes=book_ser.errors)
모델 직렬 화 기 (직렬 화 와 반 직렬 화 통합
*****
하위 경로 api / urls. pyfrom django.conf.urls import url
from . import views
urlpatterns = [
url(r'^v2/books/$', views.BookV2APIView.as_view()),
url(r'^v2/books/(?P.*)/$', views.BookV2APIView.as_view()),
]
사용자 정의 직렬 화 기 api / serializers. py
from rest_framework import serializers
from . import models
class BookV2ModelSerializer(serializers.ModelSerializer):
re_name = serializers.CharField(
min_length=3,
required=True,
write_only=True, #
error_messages={
'min_length': ' ',
'required': ' '
}
)
class Meta:
model = models.Book
fields = ('name', 're_name', 'price', 'img', 'publish', 'publish_info', 'authors', 'authors_info')
extra_kwargs = {
'name':{
'min_length': 3,
'error_messages': {
'min_length': ' ',
'required': ' '
}
},
# required False, ,
'publish':{
'required': True,
'write_only': True,
'error_messages':{
'required': ' '
}
},
'authors':{
'required': True,
'write_only': True,
'error_messages':{
'required': ' '
}
},
}
#
#
def validate_name(self, value):
if 'sb' in value:
raise serializers.ValidationError(' ')
return value
def validate(self, attr):
name = attr.get('name')
re_name = attr.get('re_name')
publish = attr.get('publish')
if name != re_name:
raise serializers.ValidationError(
{'re_name': ' '}
)
if models.Book.objects.filter(name=name, publish=publish):
raise serializers.ValidationError(
{'book': ' '}
)
return attr
보기에 서 api / views. py 사용 하기
class BookV2APIView(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 pk:
return APIResponse(1, 'pk ')
book_ser = serializers.BookV2ModelSerializer(book_obj)
return APIResponse(0, 'ok', results=book_ser.data)
#
book_obj_list = models.Book.objects.filter(is_delete=False).all()
if not book_obj_list:
return APIResponse(1, ' ')
book_ser = serializers.BookV2ModelSerializer(book_obj_list, many=True)
return APIResponse(0, 'ok', results=book_ser.data)
#
def post(self, request, *args, **kwargs):
book_ser = serializers.BookV2ModelSerializer(data=request.data)
if book_ser.is_valid():
book_obj = book_ser.save()
results = serializers.BookV2ModelSerializer(book_obj).data
return APIResponse(0, 'ok', results=results)
else:
return APIResponse(1, ' ', results=book_ser.errors)
#
def patch(self, request, *args, **kwargs):
pk = kwargs.get('pk')
if not pk:
return APIResponse(1, 'pk ')
try:
book_obj = models.Book.objects.get(is_delete=False, pk=pk)
except:
return APIResponse(1, 'pk ')
book_ser = serializers.BookV2ModelSerializer(instance=book_obj, data=request.data, partial=True)
if book_ser.is_valid():
book_obj = book_ser.save()
results = serializers.BookV2ModelSerializer(book_obj)
return APIResponse(0, 'ok', results=results)
else:
return APIResponse(1, ' ', results=book_ser.errors)
#
def put(self, request, *args, **kwargs):
pk = kwargs.get('pk')
if not pk:
return APIResponse(1, 'pk ')
try:
book_obj = models.Book.objects.get(is_delete=False, pk=pk)
except:
return APIResponse(1, 'pk ')
book_ser = serializers.BookV2ModelSerializer(instance=book_obj, data=request.data)
if book_ser.is_valid():
book_obj = book_ser.save()
results = serializers.BookV2ModelSerializer(book_obj).data
return APIResponse(0, 'ok', results=results)
else:
return APIResponse(1, ' ', results=book_ser.errors)
#
def delete(self, request, *args, **kwargs):
# /books/(pk)/
# /books/ pks => request.data
pk = kwargs.get('pk')
if pk:
pks = [pk, ]
else:
pks = request.data.get('pk')
if not pks:
return APIResponse(1, 'pk ')
book_obj_list = models.Book.objects.filter(is_delete=False, pk__in=pks)
if not book_obj_list.update(is_delete=True):
return APIResponse(1, ' ')
return APIResponse(0, ' ')
군 증 군 개
ModelSerializer 에 서 는 기본적으로 여러 대상 을 한꺼번에 반 직렬 화 할 수 없고 한 대상 만 반 직렬 화 할 수 있 기 때문에 그룹 변경 과 군 증 기능 을 실현 할 수 없 기 때문에 Meta 에 list 를 설정 해 야 합 니 다.serializer_class:
ListSerializer api/serializers.py
from rest_framework import serializers
from . import models
class BookListSerializer(serializers.ListSerializer):
def update(self, instance, validated_data):
for ind, obj in enumerate(instance):
for attr, value in validated_data[ind].items():
if hasattr(obj, attr):
set(obj, attr, value)
obj.save()
return instance
class BookV2ModelSerializer(serializers.ModelSerializer):
class Meta:
model = models.Book
fields = ('name', 're_name', 'price', 'img', 'publish', 'publish_info', 'authors', 'authors_info')
list_serializer_class = BookListSerializer
extra_kwargs = {
'name':{
'min_length': 3,
'error_messages': {
'min_length': ' ',
'required': ' '
}
},
'publish':{
'required': True,
'write_only': True,
'error_messages':{
'required': ' '
}
},
'authors':{
'required': True,
'write_only': True,
'error_messages':{
'required': ' '
}
},
}
def validate_name(self, value):
if 'sb' in value:
raise serializers.ValidationError(' ')
return value
def validate(self, attr):
name = attr.get('name')
publish = attr.get('publish')
if models.Book.objects.filter(name=name, publish=publish):
raise serializers.ValidationError(
{'book': ' '}
)
return attr
보기 층 api / views. py
class BookV2APIView(APIView):
#
def post(self, request, *args, **kwargs):
#
request_data = request.data
if isinstance(request_data, dict):
data = [request_data, ]
elif isinstance(request, list):
data = request_data
else:
return APIView(1, ' ')
book_ser = serializers.BookV2ModelSerializer(data=data, many=True)
if book_ser.is_valid():
book_obj_list = book_ser.save()
results = serializers.BookV2ModelSerializer(book_obj_list, many=True).data
return APIResponse(0, 'ok', results=results)
else:
return APIResponse(1, ' ', results=book_ser.errors)
#
def put(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_obj_list = []
filter_data = []
for ind, pk in enumerate(pks):
book_obj = models.Book.objects.filter(is_delete=False, pk=pk).first()
if book_obj:
book_obj_list.append(book_obj)
filter_data.append(data[ind])
#
book_ser = serializers.BookV2ModelSerializer(instance=book_obj_list, data=filter_data, many=True)
if book_ser.is_valid():
book_obj_list = book_ser.save()
results = serializers.BookV2ModelSerializer(book_obj_list, ).data
return APIResponse(0, 'ok', results=results)
else:
return APIResponse(1, ' ', results=book_ser.errors)
#
def patch(self, request, *args, **kwargs):
"""
/books/(pk)/ data {"name": "new_name", ...}
/books/ data [{"pk": 1, "name": "new_name", ...}, ...,{"pk": n, "name": "new_name", ...}]
:
pks = [1, ..., n] => book_query => instance
data = [{"name": "new_name", ...}, ..., {"name": "new_name", ...}] => data
"""
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_obj_list = []
filter_data = []
for ind, pk in enumerate(pks):
book_obj = models.Book.objects.filter(is_delete=False, pk=pk).first()
if book_obj:
book_obj_list.append(book_obj)
filter_data.append(data[ind])
#
book_ser = serializers.BookV2ModelSerializer(instance=book_obj_list, data=filter_data, many=True)
#
if book_ser.is_valid():
book_obj_list = book_ser.save()
results = serializers.BookV2ModelSerializer(book_obj_list, ).data
return APIResponse(0, 'ok', results=results)
#
else:
return APIResponse(1, ' ', results=book_ser.errors)
다음으로 전송:https://www.cnblogs.com/Hades123/p/11487864.html
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.