首页 > 解决方案 > Django perform_create conditional creation

问题描述

I can create a Product based on JSON data. I would like to add a condition so then if a Product already exists with the same name I don't create anything and my view returns the existing Product.

For the creation no problem, the Product is set correctly and the view returns the data (I checked in DB and it's here). But when I try to create a second product with the same name I have an error (Here I use the exact same JSON).

View :

class ProductCreate(generics.CreateAPIView):
        """ Create a new product """

        permission_classes = (permissions.IsRequestAllowed,)
        serializer_class = ProductSerializer

        def perform_create(self, serializer):

            product = product_service.get_product_from_name(serializer.validated_data['name'])

            if not product:
                LOG.debug('Creating Product from JSON data : {} '.format(serializer.validated_data))
                serializer.save()
            else:
                LOG.debug('{} already exists, JSON data : {} '.format(product, serializer.validated_data))

Serializer :

class ProductSerializer(serializers.ModelSerializer):
    class Meta:  # pylint: disable=too-few-public-methods
        model = Product
        fields = ('id',
                  'actor',
                  'brand',
                  'creation_date',
                  'description',
                  'ean_code',
                  'image',
                  'internal_code',
                  'name',
                  'price_unit',
                  'product_group',
                  'url',)

Model :

class Product(models.Model):
    actor = models.ForeignKey(Actor, related_name='products', on_delete=models.CASCADE)
    brand = models.CharField(max_length=200, blank=True)
    creation_date = models.DateTimeField(auto_now_add=True)
    description = models.CharField(max_length=1000, blank=True)
    ean_code = models.CharField(max_length=200, blank=True)
    image = models.CharField(max_length=400, blank=True)
    internal_code = models.CharField(max_length=200, blank=True)
    name = models.CharField(max_length=200, blank=False)
    price_unit = models.CharField(max_length=200, blank=True)
    product_group = models.ForeignKey(
        ProductGroup, related_name='products', blank=True, null=True, on_delete=models.CASCADE)
    url = models.CharField(max_length=400, blank=True)

Input data :

{ "actor": 1, "brand": "brand", "description": "my product desc", "ean_code": "1230456078900", "image": "img", "internal_code": "123456", "name": "my product name", "url": "my product url" }

Error :

Traceback (most recent call last):
File "/usr/local/lib/python3.6/site-packages/django/core/handlers/exception.py", line 41, in inner
        response = get_response(request)
File "/usr/local/lib/python3.6/site-packages/django/core/handlers/base.py", line 187, in _get_response
        response = self.process_exception_by_middleware(e, request)
File "/usr/local/lib/python3.6/site-packages/django/core/handlers/base.py", line 185, in _get_response
        response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/usr/local/lib/python3.6/site-packages/django/views/decorators/csrf.py", line 58, in wrapped_view
        return view_func(*args, **kwargs)
File "/usr/local/lib/python3.6/site-packages/django/views/generic/base.py", line 68, in view
        return self.dispatch(request, *args, **kwargs)
File "/usr/local/lib/python3.6/site-packages/rest_framework/views.py", line 494, in dispatch
        response = self.handle_exception(exc)
File "/usr/local/lib/python3.6/site-packages/rest_framework/views.py", line 454, in handle_exception
        self.raise_uncaught_exception(exc)
File "/usr/local/lib/python3.6/site-packages/rest_framework/views.py", line 491, in dispatch
        response = handler(request, *args, **kwargs)
File "/usr/local/lib/python3.6/site-packages/rest_framework/generics.py", line 192, in post
        return self.create(request, *args, **kwargs)
File "/usr/local/lib/python3.6/site-packages/rest_framework/mixins.py", line 22, in create
        headers = self.get_success_headers(serializer.data)
File "/usr/local/lib/python3.6/site-packages/rest_framework/serializers.py", line 537, in data
        ret = super(Serializer, self).data
File "/usr/local/lib/python3.6/site-packages/rest_framework/serializers.py", line 264, in data
        self._data = self.to_representation(self.validated_data)
File "/usr/local/lib/python3.6/site-packages/rest_framework/serializers.py", line 491, in to_representation
        attribute = field.get_attribute(instance)
File "/usr/local/lib/python3.6/site-packages/rest_framework/relations.py", line 177, in get_attribute
        return get_attribute(instance, self.source_attrs)
File "/usr/local/lib/python3.6/site-packages/rest_framework/fields.py", line 98, in get_attribute
        instance = instance[attr] KeyError: 'product_group'

标签: djangodjango-rest-frameworkserialization

解决方案


您无需做任何事情,DRF 会为您处理!

您可以在这里查看代码: https ://github.com/encode/django-rest-framework/blob/2b6245db5359571f10d27ace16473d70e160dce2/rest_framework/mixins.py#L18


推荐阅读