我正在将Python 3.6与Django 1.11.9和rest_framework 3.6.2结合使用。
我想从serializers.Serializer继承,以创建一个我想抽象的SharingSerializer类,因为我想从后者继承以实现一些ArticleSharingSerializer,ImageSharingSerializer等。
到目前为止,我已经尝试过:
from abc import ABCMeta, abstractmethod
from rest_framework import serializers
...
class SharingSerializer(serializers.Serializer, metaclass=ABCMeta):
course = serializers.PrimaryKeyRelatedField(queryset=Course.objects.all())
students = serializers.PrimaryKeyRelatedField(queryset=User.objects.all(), many=True)
@abstractmethod
def validate(self, data):
# Doing validation stuff with "course" and "students" fields
...
return data
class ArticleSharingSerializer(SharingSerializer):
articles = serializers.PrimaryKeyRelatedField(queryset=Article.objects.all(), many=True)
def validate(self, data):
data = super().validate(data)
# Doing validation stuff with "articles" and self.context["request"].user
...
return data
但是当尝试“运行服务器”时,出现以下错误:
File ".../school/serializers.py", line 11, in <module>
class SharingSerializer(serializers.Serializer, metaclass=ABCMeta):
TypeError: metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases
您知道我如何成功实现自己想要达到的目标吗?
更新:我想在ABC提供的实例化中利用@abstractmethod“ enforcement”。
更新2:TLDR:艾哈迈德·霍斯尼(Ahmed Hosny,见下文)给出的最佳答案是this link
答案 0 :(得分:0)
简短回答
要继续使用ABCMeta
,您也可以这样做,
class SharingSerializer(serializers.Serializer):
__metaclass__ = ABCMeta
course = serializers.PrimaryKeyRelatedField(queryset=Course.objects.all())
students = serializers.PrimaryKeyRelatedField(queryset=User.objects.all(), many=True)
@abstractmethod
def validate(self, data):
# Doing validation stuff with "course" and "students" fields
...
return data
或进行中级学习,请检查此OP。
详细答案:
当您尝试让一个类继承自具有不同meta_class
的两个不同类时,就会出现问题。然后发生冲突!
因此,在您的情况下,您从具有元类的serializers.Serializer
继承(选中this),并且还通过meta_class
继承了不同的metaclass=ABCMeta
。这就是发生冲突的原因。
[更新]
让我们明确几点:
正在做
class Meta:
abstract = True
不会使您的类抽象化您对Java和其他编译语言的了解。
实际上,它只是使用一些额外的属性标记了该类(无需进一步说明)。
abstract = True
是与Django相关的东西。因为Django正在进行额外的检查,以使您拥有abstract
的风格。在https://github.com/django/django/blob/master/django/db/models/base.py#L62 所以这不是特定于Django的,abstract = True
本身没有任何内容也不会做任何额外的事情。
ABC
在做类似的想法时,采用了额外且简洁的方法来具有abstract
的风格。因此,请在https://github.com/python/cpython/blob/master/Lib/abc.py