django.core.exceptions.ImproperlyConfigured:字段名称`id`对模型

时间:2018-04-02 23:34:13

标签: python django django-rest-framework

我遇到了一个串行器问题。我正在尝试返回PriceUnit对象的所有数据,但DRF拒绝提供id。 这个id是自动生成的,我不会修改它。

serializer.py

class PriceUnitSerializer(serializers.ModelSerializer):
    product_id = serializers.SerializerMethodField()

    def get_product_id(self, obj):
        if obj.product is not None:
            return obj.product.id
        return None

    class Meta:
        model = PriceUnit
        fields = ('id',
                  'name',
                  'formula',
                  'product_id')

urls.py

url(r'^price_units/$', price_unit_view.PriceUnitCreateUpdate.as_view()),
    url(r'^price_units/(?P<pk>[0-9]+)/$', price_unit_view.PriceUnitList.as_view()),

models.py

class PriceUnit(models.Model):
    UNIT = 'Unit'
    SQUAREMATER = 'm2'
    CUBEMETER = 'm3'
    LINEARMETER = 'ml'
    KILOGRAM = 'kg'

    PRICE_UNITS_CHOICES = (
        (UNIT, 'Unit'),
        (SQUAREMATER, 'm2'),
        (CUBEMETER, 'm3'),
        (LINEARMETER, 'ml'),
        (KILOGRAM, 'kg'),
    )

    name = models.CharField(max_length=50, choices=PRICE_UNITS_CHOICES, default=UNIT,)
    formula = models.CharField(max_length=400, blank=True)
    product = models.OneToOneField(Product, on_delete=models.CASCADE, primary_key=True,)

    def __str__(self):
        return 'Price unit : ' + self.name + ' - Product #' + str(self.product.pk)

price_unit_view.py

class PriceUnitList(APIView):
    """
    Retrieve a PriceUnit.
    """

    permission_classes = (permissions.IsAuthenticated,)

    def get(cls, request, pk, format=None):
        price_unit_list = PriceUnit.objects.filter(pk=pk)

        if price_unit_list:
            serializer = PriceUnitSerializer(price_unit_list[0])
            return Response(serializer.data, status=status.HTTP_200_OK)
        else:
            return Response(data={}, status=status.HTTP_204_NO_CONTENT)

请求(使用httpie):

http GET http://127.0.0.1/api/price_units/1/ "Authorization: Token ba4ee2628669a9cc0d6e715b12660003f748c674"

错误:

ERROR [django.request:135] Internal Server Error: /price_units/1/
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 "./main/views/price_unit_view.py", line 27, in get
    return Response(serializer.data, status=status.HTTP_200_OK)
  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 262, in data
    self._data = self.to_representation(self.instance)
  File "/usr/local/lib/python3.6/site-packages/rest_framework/serializers.py", line 487, in to_representation
    fields = self._readable_fields
  File "/usr/local/lib/python3.6/site-packages/django/utils/functional.py", line 35, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "/usr/local/lib/python3.6/site-packages/rest_framework/serializers.py", line 377, in _readable_fields
    field for field in self.fields.values()
  File "/usr/local/lib/python3.6/site-packages/rest_framework/serializers.py", line 363, in fields
    for key, value in self.get_fields().items():
  File "/usr/local/lib/python3.6/site-packages/rest_framework/serializers.py", line 1022, in get_fields
    source, info, model, depth
  File "/usr/local/lib/python3.6/site-packages/rest_framework/serializers.py", line 1167, in build_field
    return self.build_unknown_field(field_name, model_class)
  File "/usr/local/lib/python3.6/site-packages/rest_framework/serializers.py", line 1279, in build_unknown_field
    (field_name, model_class.__name__)
django.core.exceptions.ImproperlyConfigured: Field name `id` is not valid for model `PriceUnit`.

我的其他序列化器与此序列化器完全相同,但是可以返回id,并且完全没有问题。

我们将不胜感激。

2 个答案:

答案 0 :(得分:0)

如错误所示,您的模型没有id字段。它有三个字段nameformulaproductprimary_key=True字段为product,因此Django不会自动创建id字段。

答案 1 :(得分:0)

您已明确设置主键,但不会添加自动id列。看看Automatic Primary Key Documentation。下面更新的模型现在适合您。

class PriceUnit(models.Model):
UNIT = 'Unit'
SQUAREMATER = 'm2'
CUBEMETER = 'm3'
LINEARMETER = 'ml'
KILOGRAM = 'kg'

PRICE_UNITS_CHOICES = (
    (UNIT, 'Unit'),
    (SQUAREMATER, 'm2'),
    (CUBEMETER, 'm3'),
    (LINEARMETER, 'ml'),
    (KILOGRAM, 'kg'),
)

name = models.CharField(max_length=50, choices=PRICE_UNITS_CHOICES, default=UNIT)
formula = models.CharField(max_length=400, blank=True)
product = models.OneToOneField(Product, on_delete=models.CASCADE)