创建能够序列化 Django Rest Framework 中基本模型的所有子类的通用序列化程序的最佳方法是什么?
What's the best way to create a generic serializer which is able to serialize all the subclasses of the base model in Django Rest Framework?
我目前正在开发一个通知系统,它将通过 API.
传递许多不同类型的通知
我有一个名为 BaseNotification
的基本通知 class。这是代码:
class BaseNotification(models.Model):
message = models.CharField(max_length=500)
seen = models.BooleanField(default=True)
class Meta:
abstract = True
我想子class这个模型来创建不同的通知变体:
class InvitationNotification(BaseNotification):
invited_user = models.ForeignKey(User, on_delete=models.CASCADE)
campagin = models.ForeignKey(Campagin, on_delete=models.CASCADE)
# ... the rest of specific fields
class ChatMessageNotification(BaseNotification):
contact = models.ForeignKey(User, on_delete=models.CASCADE)
chat_room = models.ForeignKey(SomeSortOfChatRoomWhichIsNotImplementedYet, on_delete=models.CASCADE)
# ... the rest of specific fields
如您所见,这些变体中的每一个都有一些与之关联的元数据。前端开发人员将能够使用这些元数据创建用户交互(例如,在聊天消息的情况下,前端开发人员会将用户重定向到聊天室)
我想通过一个统一的方式列出所有这些通知 API。为此,我需要一个序列化程序来将对象序列化为 json 但我不想为每个对象都有一个单独的序列化程序。理想情况下,我想要一个通用的序列化程序,它能够序列化所有类型的通知,并根据传入的通知对象的类型生成不同的 json 输出。(它可能在后台使用其他序列化程序)。
也许我走错了路,但最终目标是通过一个统一的 API.
传递通知及其所有元数据
我真的需要你的建议和帮助。提前谢谢大家。
我终于自己弄明白了。我的最终目标是为前端开发人员提供一些元数据,以便他可以根据通知类型实现用户交互。
我用一个JSONField
简单的解决了这个问题。这很好用,这是我唯一需要的东西。
models.py
class Notification(models.Model):
NEW_MEMBER_JOINED = 'NEW_MEMBER_JOINED'
INVITATION = 'INVITATION'
TEXT = 'TEXT'
NEW_POST_CREATED = 'NEW_POST_CREATED'
NEW_MESSAGE = 'NEW_MESSAGE'
NEW_CAMPAIGN_CONTENT = 'NEW_CAMPAIGN_CONTENT'
NEW_COMMENT = 'NEW_COMMENT'
target = models.ForeignKey(User, on_delete=models.CASCADE, related_name='notifications')
text = models.CharField(max_length=300)
type = models.CharField(max_length=255)
date_created = models.DateTimeField(auto_now_add=True)
seen = models.BooleanField(default=False)
metadata = models.JSONField(null=True, blank=True)
def __str__(self) -> str:
return f"[{self.type}] {self.text}"
serializers.py
class NotificationSerializer(serializers.ModelSerializer):
class Meta:
model = Notification
fields = '__all__'
read_only_fields = [
'text', 'type', 'metadata', 'date_created', 'seen'
]
就我而言,此解决方案效果最好。
我目前正在开发一个通知系统,它将通过 API.
传递许多不同类型的通知我有一个名为 BaseNotification
的基本通知 class。这是代码:
class BaseNotification(models.Model):
message = models.CharField(max_length=500)
seen = models.BooleanField(default=True)
class Meta:
abstract = True
我想子class这个模型来创建不同的通知变体:
class InvitationNotification(BaseNotification):
invited_user = models.ForeignKey(User, on_delete=models.CASCADE)
campagin = models.ForeignKey(Campagin, on_delete=models.CASCADE)
# ... the rest of specific fields
class ChatMessageNotification(BaseNotification):
contact = models.ForeignKey(User, on_delete=models.CASCADE)
chat_room = models.ForeignKey(SomeSortOfChatRoomWhichIsNotImplementedYet, on_delete=models.CASCADE)
# ... the rest of specific fields
如您所见,这些变体中的每一个都有一些与之关联的元数据。前端开发人员将能够使用这些元数据创建用户交互(例如,在聊天消息的情况下,前端开发人员会将用户重定向到聊天室)
我想通过一个统一的方式列出所有这些通知 API。为此,我需要一个序列化程序来将对象序列化为 json 但我不想为每个对象都有一个单独的序列化程序。理想情况下,我想要一个通用的序列化程序,它能够序列化所有类型的通知,并根据传入的通知对象的类型生成不同的 json 输出。(它可能在后台使用其他序列化程序)。
也许我走错了路,但最终目标是通过一个统一的 API.
传递通知及其所有元数据我真的需要你的建议和帮助。提前谢谢大家。
我终于自己弄明白了。我的最终目标是为前端开发人员提供一些元数据,以便他可以根据通知类型实现用户交互。
我用一个JSONField
简单的解决了这个问题。这很好用,这是我唯一需要的东西。
models.py
class Notification(models.Model):
NEW_MEMBER_JOINED = 'NEW_MEMBER_JOINED'
INVITATION = 'INVITATION'
TEXT = 'TEXT'
NEW_POST_CREATED = 'NEW_POST_CREATED'
NEW_MESSAGE = 'NEW_MESSAGE'
NEW_CAMPAIGN_CONTENT = 'NEW_CAMPAIGN_CONTENT'
NEW_COMMENT = 'NEW_COMMENT'
target = models.ForeignKey(User, on_delete=models.CASCADE, related_name='notifications')
text = models.CharField(max_length=300)
type = models.CharField(max_length=255)
date_created = models.DateTimeField(auto_now_add=True)
seen = models.BooleanField(default=False)
metadata = models.JSONField(null=True, blank=True)
def __str__(self) -> str:
return f"[{self.type}] {self.text}"
serializers.py
class NotificationSerializer(serializers.ModelSerializer):
class Meta:
model = Notification
fields = '__all__'
read_only_fields = [
'text', 'type', 'metadata', 'date_created', 'seen'
]
就我而言,此解决方案效果最好。