python - DRF : Cannot POST or create a new object through admin interface

标签 python django django-rest-framework

当我尝试通过管理界面创建新对象时,出现以下错误:

TypeError: unsupported operand type(s) for %: 'ImproperlyConfigured' and 'tuple'

我有以下型号:

class CustomUser(AbstractUser):
    def __str__(self):
        return self.email

    class Meta:
        ordering = ('id',)
        verbose_name = 'user'

class Address(models.Model):
    """Address contains information about location. Address can be own by any
    kind of model."""
    content_type = models.ForeignKey(
        ContentType, on_delete=models.CASCADE, null=True
    )
    object_id = models.PositiveIntegerField(null=True)
    owner = GenericForeignKey("content_type", "object_id")

    CATEGORIES = Choices('billing', 'shipping')
    category = models.CharField(choices=CATEGORIES, max_length=16)
    address_1 = models.CharField("address line 1", max_length=128)
    address_2 = models.CharField("address line 2", max_length=128, blank=True)
    city = models.CharField(max_length=64)
    state_province = models.CharField('state/province', max_length=128)
    country = CountryField(blank_label='(select country)')
    zip_code = models.CharField(max_length=10)

    def __str__(self):
        return (
            f'{self.address_1}, {self.city}, {self.state_province}, '
            f'{self.country.name}, {self.zip_code}'
        )

    class Meta:
        ordering = ('id',)

class Company(Group):
    """An abstract base class that inherits Group."""
    addresses = GenericRelation(Address)
    owner = models.ForeignKey(User,
                              on_delete=models.CASCADE,
                              related_name='%(class)ss',
                              related_query_name='%(class)s')
    logo = CloudinaryField('image',
                           default='your_logo_here',
                           null=True,
                           blank=True)
    description = models.TextField('description', max_length=3000, blank=True)
    facebook_url = models.URLField('facebook url', blank=True)
    twitter_url = models.URLField('twitter url', blank=True)
    instagram_url = models.URLField('instagram url', blank=True)
    pinterest_url = models.URLField('pinterest url', blank=True)
    portfolio_url = models.URLField('portfolio url',  blank=True)
    phone_number = PhoneNumberField('phone number', blank=True)

    class Meta:
        abstract = True
        ordering = ('id',)


class Brand(Company):
    """A Brand can have multiple members."""

这些是我的序列化器:

class CustomUserSerializer(HyperlinkedModelSerializer):
    brands = HyperlinkedRelatedField(
        many=True,
        read_only=True,
        view_name='brand-detail'
    )

    class Meta:
        model = CustomUser
        fields = (
            'url',
            'username',
            'email',
            'brands',
        )

class AddressSerializer(HyperlinkedModelSerializer):
    owner = GenericRelatedField({
        Brand: HyperlinkedRelatedField(
            queryset=Brand.objects.all(),
            view_name='brand-detail',
        )
    })

    class Meta:
        model = Address
        fields = (
            'url',
            'category',
            'address_1',
            'address_2',
            'city',
            'state_province',
            'country',
            'zip_code',
            'owner',
        )


class BrandSerializer(HyperlinkedModelSerializer):
    addresses = HyperlinkedRelatedField(many=True,
                                        read_only=True,
                                        view_name='address-detail')

    class Meta:
        model = Brand
        fields = (
            'url',
            'owner',
            'logo',
            'description',
            'facebook_url',
            'twitter_url',
            'instagram_url',
            'pinterest_url',
            'portfolio_url',
            'phone_number',
            'addresses',
        )

这就是我配置网址的方式:

router = DefaultRouter()
router.register('users', CustomUserViewSet)
router.register('addresses', AddressViewSet)
router.register('brands', BrandViewSet)

urlpatterns = [
    path('', include(router.urls)),
    path('auth/', include('rest_framework.urls', namespace='rest_framework')),
]

我可以访问http://localhost:8000/api/addresses/,并且我有以下形式:

enter image description here

问题是当我尝试 POST 创建新对象时。我收到了我所描述的错误,似乎是因为我没有正确传递所有者(实际上我不知道如何在这里传递对象,我应该使用 JSON 或如何使用)。

enter image description here

问题:

  1. 如何解决此错误,因为我也在尝试测试 POST 方法,但当我意识到这不起作用时?

  2. 有没有办法在该表单中包含 GenericForeignKey 的字段?

这是我的回溯:

File "/Users/user/.local/share/virtualenvs/na-ERB0uoVd/lib/python3.7/site-packages/generic_relations/serializers.py" in to_internal_value
  39.             serializer = self.get_deserializer_for_data(data)

File "/Users/user/.local/share/virtualenvs/na-ERB0uoVd/lib/python3.7/site-packages/generic_relations/serializers.py" in get_deserializer_for_data
  75.                 'Could not determine a valid serializer for value %r.' % value)

During handling of the above exception (Could not determine a valid serializer for value ''.), another exception occurred:

File "/Users/user/.local/share/virtualenvs/na-ERB0uoVd/lib/python3.7/site-packages/rest_framework/serializers.py" in to_internal_value
  488.                 validated_value = field.run_validation(primitive_value)

File "/Users/user/.local/share/virtualenvs/na-ERB0uoVd/lib/python3.7/site-packages/rest_framework/fields.py" in run_validation
  536.         value = self.to_internal_value(data)

File "/Users/user/.local/share/virtualenvs/na-ERB0uoVd/lib/python3.7/site-packages/generic_relations/serializers.py" in to_internal_value
  41.             raise ValidationError(e)

During handling of the above exception (["Could not determine a valid serializer for value ''."]), another exception occurred:

File "/Users/user/.local/share/virtualenvs/na-ERB0uoVd/lib/python3.7/site-packages/rest_framework/fields.py" in get_error_detail
  240.         error_dict = exc_info.error_dict

During handling of the above exception ('ValidationError' object has no attribute 'error_dict'), another exception occurred:

File "/Users/user/.local/share/virtualenvs/na-ERB0uoVd/lib/python3.7/site-packages/django/core/handlers/exception.py" in inner
  34.             response = get_response(request)

File "/Users/user/.local/share/virtualenvs/na-ERB0uoVd/lib/python3.7/site-packages/django/core/handlers/base.py" in _get_response
  126.                 response = self.process_exception_by_middleware(e, request)

File "/Users/user/.local/share/virtualenvs/na-ERB0uoVd/lib/python3.7/site-packages/django/core/handlers/base.py" in _get_response
  124.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "/Users/user/.local/share/virtualenvs/na-ERB0uoVd/lib/python3.7/site-packages/django/views/decorators/csrf.py" in wrapped_view
  54.         return view_func(*args, **kwargs)

File "/Users/user/.local/share/virtualenvs/na-ERB0uoVd/lib/python3.7/site-packages/rest_framework/viewsets.py" in view
  116.             return self.dispatch(request, *args, **kwargs)

File "/Users/user/.local/share/virtualenvs/na-ERB0uoVd/lib/python3.7/site-packages/rest_framework/views.py" in dispatch
  495.             response = self.handle_exception(exc)

File "/Users/user/.local/share/virtualenvs/na-ERB0uoVd/lib/python3.7/site-packages/rest_framework/views.py" in handle_exception
  455.             self.raise_uncaught_exception(exc)

File "/Users/user/.local/share/virtualenvs/na-ERB0uoVd/lib/python3.7/site-packages/rest_framework/views.py" in dispatch
  492.             response = handler(request, *args, **kwargs)

File "/Users/user/.local/share/virtualenvs/na-ERB0uoVd/lib/python3.7/site-packages/rest_framework/mixins.py" in create
  20.         serializer.is_valid(raise_exception=True)

File "/Users/user/.local/share/virtualenvs/na-ERB0uoVd/lib/python3.7/site-packages/rest_framework/serializers.py" in is_valid
  236.                 self._validated_data = self.run_validation(self.initial_data)

File "/Users/user/.local/share/virtualenvs/na-ERB0uoVd/lib/python3.7/site-packages/rest_framework/serializers.py" in run_validation
  434.         value = self.to_internal_value(data)

File "/Users/user/.local/share/virtualenvs/na-ERB0uoVd/lib/python3.7/site-packages/rest_framework/serializers.py" in to_internal_value
  494.                 errors[field.field_name] = get_error_detail(exc)

File "/Users/user/.local/share/virtualenvs/na-ERB0uoVd/lib/python3.7/site-packages/rest_framework/fields.py" in get_error_detail
  245.             for error in exc_info.error_list]

File "/Users/user/.local/share/virtualenvs/na-ERB0uoVd/lib/python3.7/site-packages/rest_framework/fields.py" in <listcomp>
  245.             for error in exc_info.error_list]

Exception Type: TypeError at /api/addresses/
Exception Value: unsupported operand type(s) for %: 'ImproperlyConfigured' and 'tuple'

最佳答案

如果添加 read_only=True 如下:

owner = GenericRelatedField({
    Brand: HyperlinkedRelatedField(
        queryset=Brand.objects.all(),
        view_name='brand-detail',
    )
}, read_only=True)

错误将会消失。但是你需要写你的 在同一个序列化器中拥有自己的 create() 方法,并使用所有者的序列化来说明如何 你想救主人。

关于python - DRF : Cannot POST or create a new object through admin interface,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53440189/

相关文章:

python - DRF 序列化程序更新嵌套用户

python - 如何在 DRF 中的序列化程序验证/保存之前添加其他数据?

python - 列出 Google 云端硬盘文件时出错

python - 确定多嘌呤束的长度

python - 如何使用反射或解析读取Python类中声明成员的顺序(禁止元类替换)?

python - Django 在 Save() 之后立即更新表

python - Django REST Framework 不以 PUT 形式显示值

python - 无法识别人眼图像中的虹膜区域

python - Django 模板过滤器查询集

python - 如何将unicode原始python类型转换