Django Rest Framework: правильный способ переопределить execute_create в ModelViewSet? - PullRequest
0 голосов
/ 13 июня 2018

Теперь я решил эту проблему, поэтому прокрутите вниз до нижней части вопроса, чтобы увидеть разрешение

В Django Rest Framework, когда вставка выполняется в одну модель, я хотел быделать обновления / вставки на других моделях.

Я работаю с ModelViewSet, и я попытался переопределить метод perform_create, но исходная вставка просто проглатывается, обновление не происходит и ошибок нетвидел.

Я пытался сделать это

def perform_create(self, serializer):
    serializer.save()

, но, несмотря на отсутствие ошибок, обновление также не происходит.

Был бы признателен за пример переопределения perform_createтак что оригинальная вставка все еще имеет место, но есть возможность для других обновлений / вставок одновременно.

Я использую DRF 3.5.3.


РЕДАКТИРОВАТЬ: Здесьэто полный код ModelViewSet.

class AttemptViewSet(viewsets.ModelViewSet):
    '''
    API endpoint that allows Attempt to be CRUDed.
    '''

    queryset = Attempt.objects.all()
    serializer_class = AttemptSerializer
    authentication_classes = (TokenAuthentication,)
    permission_classes = (IsAuthenticated,)

    def perform_create(self, serializer):
        import pdb;pdb.set_trace()
        serializer.save()

    def initial(self, request, *args, **kwargs):
        '''
        Temporary diagnostic code which should
        be removed once it's possible to update
        an Attempt
        '''

        import os
        import json

        # 'request_auth': request.auth,
        log_data = {
            'user': request.user.pk,

            'remote_address': request.META['REMOTE_ADDR'],

            'request_method': request.method,
            'request_path': request.get_full_path(),
            'request_body': request.data ,
            'request_query_params': request.query_params
        }
        if not os.path.exists('/tmp/spellsplashlog'):
            os.makedirs('/tmp/spellsplashlog')

        with open('/tmp/spellsplashlog/logging.json', 'w') as f:
            json.dump(log_data, f, sort_keys=True, indent=4)

        viewsets.ModelViewSet.initial(self, request, *args, **kwargs)

... а вот сериализатор ...

class AttemptSerializer(serializers.ModelSerializer):
    class Meta:
        model = Attempt
        fields = '__all__'

... а вот модель ...

class Attempt(models.Model):
    learner = models.ForeignKey(Learner, related_name='learnerattempts')
    word = models.ForeignKey(Word, related_name='wordattempts')
    when = models.DateTimeField(auto_now_add=True)
    success = models.BooleanField(default=False)

    class Meta:
        ordering = ['-when']

    class JSONAPIMeta:
        resource_name = "attempts"

    def __str__(self):
        formatted_when = localtime(self.when).strftime('%d-%b-%Y %X')
        if self.success:
            formatted_success = "YES"
        else:
            formatted_success = "NO"

        return u'%s - %s- Success ?: %s ' % (self.word, formatted_when, formatted_success)

РЕДАКТИРОВАТЬ (и разрешение)

ОК, поэтому я внес некоторые изменения в perform_create икажется, что в некотором смысле весьма хитрым способом DRF просто не нравится встраивание pdb.set_trace.Это не терпит неудачу, но это просто не отвечает.Как только я убрал его, он работал так, как я ожидал.

FWIW в ходе расследования я также изменил

serializer.save

на

super().perform_create(serializer)

, но на самом деле любой изэти двое сработали после того, как pdb.set_trace были удалены.

1 Ответ

0 голосов
/ 13 июня 2018

вы можете обновить другую модель после того, как метод serializer.save получит вызов.

def perform_create(serializer):
    serializer.save()
    ### here you can write the other logic of update
    ### you can use the signal, just raise signal on save of that model
...