Коллеги, новичек в Django Rest Framework. Да и вообще в python
Есть ViewSet
class DocViewSet(viewsets.ModelViewSet):
queryset = Doc.objects.all()
serializer_class = DocSerializer
...
@list_route(methods=['post'])
def createby(self, request):
"""
Создание документа по атрибутам
"""
req = request.data
ddate = req.get('ddate')
nameTypeDoc = req.get('typedoc')
nameContact = req.get('contact')
comment = req.get('comment')
doc = Doc.createBy(nameTypeDoc, nameContact, ddate, comment)
serializer = self.get_serializer(doc)
return Response(serializer.data)
...
Что не нравится.
1. Из request дергаются атрибуты создаваемого док-та. Ладно. Между получением атрибутов и Doc.create хотелось бы воткнуть валидатор. Валидировать прямо в методе не красиво. Ну допустим:
...
comment = req.get('comment')
if SomeValidator.isValid(ddate,nameTypeDoc,nameContact,comment):
doc = Doc.createBy(nameTypeDoc, nameContact, ddate, comment)
...
В каком-то другом методе будет другой валидатор. Возникает куча зависимостей от валидаторов.
Из ViewSet напрямую дергаю метод модели.
class Doc(models.Model):
"""
Заголовок документа
"""
n = models.AutoField(primary_key=True)
typeDoc = models.ForeignKey('TypeDoc', default=1, db_column='typedoc_n')
ddate = models.DateField(default=date.today())
contact = models.ForeignKey('Contact', default=1, db_column='contact_n')
...
@staticmethod
def createBy(nameTypeDoc=None, nameContact=None, ddate=None, comment=''):
"""
Создание документа по названию типа и имени контакта
ddate в формате 'YYYY-mm-dd'
"""
typeDoc = TypeDoc().getByName(nameTypeDoc)
contact = Contact().getOrCreate(nameContact)
if ddate is None:
_ddate = date.today()
else:
d = datetime.strptime(ddate, '%Y-%m-%d')
_ddate = date(d.year, d.month, d.day)
doc = Doc(contact=contact, typeDoc=typeDoc, ddate=_ddate, comment=comment)
doc.save()
return doc
В параметрах
@staticmethod
def createBy(nameTypeDoc=None, nameContact=None, ddate=None, comment=''):
nameTypeDoc,nameContact. Получается в модель Doc нужно закинуть зависимости TypeDoc и Contact. Ваще не здорово!
3.
serializer = self.get_serializer(doc)
Для этого метода пусть будет сериализатор по умолчанию. Для другого нужен другой. Можно так:
class DocViewSetFilter(filters.FilterSet):
serializer_classes = {
'createby': DocShortSerializer,
'get_with_docitems': DocFullSerializer,
Еще один пласт зависимостей.
Че-то как-то жирно.
Получается нужен какой-то слой бизнес-логики DocService , ктр. связывает Doc, Contact, TypeDoc. Зависимости от валидаторов и сериализаторов вроде все-таки остаются тут.
Вообще хотелось бы нечто следующее:
from models import TypeDoc, Contact, Doc
class DocController :
def createby(params)
typeDoc = TypeDoc().getByName(nameTypeDoc)
contact = Contact().getOrCreate(nameContact)
if ddate is None:
_ddate = date.today()
else:
d = datetime.strptime(ddate, '%Y-%m-%d')
_ddate = date(d.year, d.month, d.day)
doc = Doc(contact=contact, typeDoc=typeDoc, ddate=_ddate, comment=comment)
doc.save()
return doc
....
В DocViewSet закинуть import DocCreator
Так что-ли?
Очень не нравится что класс DocViewSet будет иметь много методов , да еще и с кучей зависимостей. Может через mixin решать? В общем как у вас принято? А вообще хотелось бы какой нибудь типовой проект посмотреть с drf. Но не уровня HelloWorld
Updated 27 July 2017, 8:33 by vasi.che.