2016-09-29 4 views
0

Я разрабатываю API, используя django-rest-framework-mongoengine с MongoDb, я хочу, чтобы добавить дополнительные поля в запрос от serializer на основе данных, вводимых пользователем, например, Если пользователь вводит keyword = @rohit49khatri, я хочу добавить еще два поля для запроса путем манипулирования keyword, как type = username, username = rohit49khatriКак добавить дополнительные поля на основе входов в Джанго рамочным отдых mongoengine

Вот мой код:

Serializer

class SocialFeedCreateSerializer(DocumentSerializer): 
    type = 'username' 

    class Meta: 
     model = SocialFeedSearchTerm 
     fields = [ 
      'keyword', 
      'type', 
     ] 
     read_only_fields = [ 
      'type' 
     ] 

Посмотреть

class SocialFeedCreateAPIView(CreateAPIView): 
    queryset = SocialFeed.objects.all() 
    serializer_class = SocialFeedCreateSerializer 

    def perform_create(self, serializer): 
     print(self.request.POST.get('type')) 

Но когда я печатаю type параметр, он дает None

Пожалуйста, помогите мне сэкономить время. Благодарю.

ответ

1

Дополнительный вопрос: как получить type параметр?

# access it via `django rest framework request` 
self.request.data.get('type', None) 
# or via `django request` 
self.request.request.POST.get('type', None) 

первоначального вопроса:

ситуации 1) ИМХО для вас ситуации, perform_create может справиться с этим:

def perform_create(self, serializer): 
    foo = self.request.data.get('foo', None) 
    bar = extract_bar_from_foo(foo) 
    serializer.save(
     additional_foo='abc', 
     additional_bar=bar, 
    ) 

ситуации 2) Если вам нужно манипулировать он перед данными переходит в сериализатор (так что управляемые данные будут проходить через проверку сериализатора):

class SocialFeedCreateAPIView(CreateAPIView): 
    queryset = SocialFeed.objects.all() 
    serializer_class = SocialFeedCreateSerializer 

    def create(self, request, *args, **kwargs): 
     # you can check the original snipeet in rest_framework/mixin 
     # original: serializer = self.get_serializer(data=request.data) 
     request_data = self.get_create_data() if hasattr(self, 'get_create_data') else request.data 
     serializer = self.get_serializer(data=request_data) 
     serializer.is_valid(raise_exception=True) 
     self.perform_create(serializer) 
     headers = self.get_success_headers(serializer.data) 
     return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers) 

    def get_create_data(self): 
     data = self.request.data.copy() 
     # manipulte your data 
     data['foo'] = 'foo' 
     return data 

ситуация 3) Если вам нужно манипулировать запрос: (вот только один пример, вы можете попытаться найти другое место, чтобы манипулировать запрос)

class SocialFeedCreateAPIView(CreateAPIView): 
    queryset = SocialFeed.objects.all() 
    serializer_class = SocialFeedCreateSerializer 

    def initial(self, request, *args, **kwargs): 
     # or any other condition you want 
     if self.request.method.lower() == 'post': 
      data = self.request.data 
      # manipulate it 
      data['foo'] = 'foo' 
      request._request.POST = data 
     return super(SocialFeedCreateAPIView, self).initial(request, *args, **kwargs) 
+0

Можно ли это сделать. в 'serializer' после проверки? –

+0

@RohitKhatri ситуация 1 (IMHO для вас ситуация, perform_create может справиться с ней) является одной после проверки .... Я обновлю ответ, чтобы добавить порядок ситуации .... – soooooot

+0

Спасибо, он решил мою проблему :-) –