Как я могу переопределить метод представления Django Rest Framework Perform_create(), чтобы установить значение по умолчанию для поля

У меня есть модель под названием Product и два набора представлений, которые по-разному управляют одной и той же моделью. Каждый из них должен установить другое значение для поля product_type, которое установлено только для чтения в сериализаторе SuplementSerializer.

Я пытаюсь переопределить метод perform_create() и установить значение для поля product_type, но оно всегда принимает значение по умолчанию.

Это моя модель:

class Product(models.Model):
    ROOM = 'ROOM'
    SUPLEMENT = 'SUPLEMENT'
    PRODUCT_TYPE_CHOICES = (
        (ROOM, _('Room')),
        (SUPLEMENT, _('Suplement'))
    )

    hotel = models.ForeignKey(Hotel, on_delete=models.PROTECT, related_name='products', verbose_name=_('Hotel'))
    name = models.CharField(max_length=100, verbose_name=_('Name'))
    product_type = models.CharField(max_length=9, choices=PRODUCT_TYPE_CHOICES, default=ROOM, verbose_name=_('Product Type'))
    room_type = models.ForeignKey(RoomType, null=True, blank=True, on_delete=models.PROTECT, related_name='products', verbose_name=_('Room Type'))
    plan_type = models.ForeignKey(PlanType, null=True, blank=True, on_delete=models.PROTECT, related_name='products', verbose_name=_('Plan Type'))
    content_type = models.ForeignKey(ContentType, null=True, blank=True, on_delete=models.PROTECT, related_name='rate_base_products', verbose_name=_('Rate Base'))
    object_id = models.PositiveIntegerField(null=True, blank=True)
    rate_base = GenericForeignKey('content_type', 'object_id')

    class Meta:
        verbose_name = _('Product')
        verbose_name_plural = _('Products')

    def __str__(self):
        return "[{}][{}]{}".format(self.id, self.hotel, self.name)

    def save(self, *vars, **kwargs):
        self.full_clean()
        return super().save(*vars, **kwargs)

    def clean(self, *vars, **kwargs):
        if self.content_type != None:
            if self.content_type.model != 'ages' and self.content_type.model != 'roombase' and self.content_type.model != 'product':
                raise CustomValidation(_("rate_base must be an instance of either 'Ages' or a 'RoomBase'"), 'rate_base', status.HTTP_400_BAD_REQUEST)

Это мои виды:

class SuplementViewSet(viewsets.ModelViewSet):
    permission_classes = (permissions.IsAuthenticated,)
    queryset = models.Product.objects.filter(product_type=models.Product.SUPLEMENT)
    serializer_class = serializers.SuplementSerializer
    filter_backends = (DjangoFilterBackend, SearchFilter, OrderingFilter,)
    search_fields = ('hotel__name', 'name')

    def perform_create(self, instance):
        instance.product_type = models.Product.SUPLEMENT
        instance.save()

class ProductViewSet(viewsets.ModelViewSet):
    permission_classes = (permissions.IsAuthenticated,)
    queryset = models.Product.objects.all()
    serializer_class = serializers.ProductSerializer
    filter_backends = (DjangoFilterBackend, SearchFilter, OrderingFilter,)
    search_fields = ('hotel__name', 'name')
    filter_fields = ('hotel__name', 'name')

И это мой сериализатор:

class SuplementSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Product
        fields = ('id', 'hotel', 'product_type', 'name')
        read_only_fields = ('product_type',)

    def __init__(self, *args, **kwargs):
        exclude = kwargs.pop('exclude', None)

        super(SuplementSerializer, self).__init__(*args, **kwargs)

        if exclude is not None:
            for field_name in exclude:
                self.fields.pop(field_name)

Я не знаю, почему я не могу установить значение для поля product_type.


person HuLu ViCa    schedule 11.07.2018    source источник


Ответы (1)


Аргументом метода perform_create() является экземпляр сериализатора, а не экземпляр объекта. Вы можете установить поле, как показано ниже

def perform_create(self, serz):
    serz.save(product_type=models.Product.SUPLEMENT)

См. объяснение здесь http://www.django-rest-framework.org/tutorial/6-viewsets-and-routers/#refactoring-to-use-viewsets

person Rohan    schedule 11.07.2018