是否有一种明显的方法来覆盖DRF从可重复使用的应用程序中用于视图集的序列化器?
我有一个使用ModelSerializer
子类的ViewSet
。我想在其中添加一个字段。但是,我想将模型和与此外部字段相关的所有其他内容都放入一个单独的应用程序中,因为它不是核心功能的一部分。
单独的应用程序可以取决于Core Django项目中的应用程序,而不是反之亦然。显然,这不是真正可重复使用的,但让我们仍然使用此术语来简单。
因此,对于一个人为的示例,可以说我在核心项目中的应用程序中有一个简单的Employee
模型,我想添加一个"可重复使用"的应用程序,该应用程序允许存储员工的Facebook配置文件。因此,我将在" core_app"中拥有以下模型,视图集和串行化器:
models.py
from django.contrib.auth.models import User
from django.db import models
class Employee(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
department = models.CharField(max_length=100)
viewsets.py
from rest_framework import viewsets
from .models import Employee
from .serializers import EmployeeSerializer
class EmployeeViewSet(viewsets.ReadOnlyModelViewSet):
queryset = Employee.objects.all()
serializer_class = EmployeeSerializer
serializers.py
from rest_framework import serializers
from .models import Employee
class EmployeeSerializer(serializers.ModelSerializer):
username = serializers.CharField(source="user.username")
class Meta:
model = Employee
fields = ["username", "department"]
现在,我有一个可重复使用的应用程序,该应用在Employee
模型中具有带有OneToOneField
的模型,以及一个添加所需字段的串行器子类:
models.py
from django.db import models
from core_app.models import Employee
class FacebookProfile(models.Model):
employee = models.OneToOneField(Employee, on_delete=models.CASCADE)
facebook_profile_link = models.CharField(max_length=1024)
serializers.py
from rest_framework import serializers
from core_app.models import Employee
from core_app.serializers import EmployeeSerializer
class FacebookProfileEmployeeSerializer(EmployeeSerializer):
facebook_profile_link = serializers.CharField(source="facebookprofile")
class Meta:
model = Employee
fields = ["username", "department", "facebook_profile_link"]
基本上,我想使core_app.viewsets.EmployeeViewSet
使用"可重复使用"应用程序而不是core_app.serializers.EmployeeSerializer
使用FacebookProfileEmployeeSerializer
。我不想对core_app
进行任何更改,也不需要对Django项目进行任何更改(除了将"可重复使用"应用程序添加到INSTALLED_SETTINGS
之外(。
我可以在"可重复使用"应用程序中覆盖完整的core_app.viewsets.EmployeeViewSet
,然后通过在ROOT_URLCONF
中覆盖URL在原始应用程序上使用它,但这不是一个不错的解决方案,需要我更改项目。
另一个明显的解决方案仅替换core_app.viewsets.EmployeeViewSet
使用的序列化器将是猴子修补。如果可能的话,我想避免这种情况,因为它是一种可能导致可维护性问题的骇客解决方案,也可能需要我更改项目,在导入原件之前对序列化处理进行修补。
因此,如果有一种更明确的方法来做到这一点。我试图找到一种更好的方法,但找不到到目前为止。
在我的"可重复使用"应用中覆盖完整的core_app.viewsets.employeeviewsets,然后通过在root_urlconf中覆盖URL来将其用于原始版本,但这不是一个不错的解决方案,并且需要我更改项目。
我建议:
facebook/viewsets.py
:
from core_app.viewsets import EmployeeViewSet
from .serializers import FacebookProfileEmployeeSerializer
class FacebookProfileEmployeeViewSet(EmployeeViewSet):
serializer_class = FacebookProfileEmployeeSerializer
然后在urls.py
# Note that we use FacebookProfileEmployeeViewSet in preference to EmployeeViewSet
router.register(r"employee", FacebookProfileEmployeeViewSet)
我认为第三方应用需要2步安装:
非常普遍- 在设置中将应用程序添加到
INSTALLED_APPS
- 将URL添加到
urls.py