python - Django rest框架从Serializer继承一个类并使其抽象
问题描述
我将 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“强制”。
更新 2:TLDR:Ahmed Hosny 给出的最佳答案(见下文)是这个链接
解决方案
简答
要继续使用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
一个元类(检查这个),并且你继承了一个不同meta_class
的 by metaclass=ABCMeta
。这就是发生冲突的原因。
[更新]
让我们明确几点:
正在做
class Meta: abstract = True
不会使您的类抽象为您在 Java 和其他编译语言中所知道的方式。
它实际上所做的只是用一些额外的属性标记这个类(没有更多细节)。
- 为什么人们可能会认为
abstract = True
是 Django 相关的东西。因为 Django 正在abstract
为你做额外的检查。在此处查看 Django 源代码https://github.com/django/django/blob/master/django/db/models/base.py#L62
所以它不是 Django 特定的,abstract = True
单独没有任何东西也不会做任何额外的事情。
ABC
正在做一个类似的想法,以额外和整洁的方式来获得这种abstract
味道。所以,在这里查看 ABC 的源代码https://github.com/python/cpython/blob/master/Lib/abc.py
推荐阅读
- c# - 如何防止在单击 Windows Toast 时启动 UWP 应用程序
- typescript - 如何在浏览器中使用 TypeScript?.NetCore Web 应用程序
- c - SCHED_OTHER 调度策略的优先级
- angular - keycloak-angular:被 CORS 策略阻止:请求的资源上不存在“Access-Control-Allow-Origin”标头
- sql - 在递归 SQL 查询中使用全局列表来避免访问节点
- python - 内存递归与循环
- snowflake-cloud-data-platform - 雪花火花连接器可以创建外部表吗?
- python - 如何将 print() 设置为 docx python
- .net - Azure 密钥保管库。这个怎么运作?
- python - AdvancePythonScheduler 暂停作业