Django模型Mixin字段不生效且django-rest-framework无法识别如何解决
问题根因
普通object派生的Mixin类不会被Django的模型元类扫描,类下定义的模型字段只会作为普通类属性存在,不会被识别为数据库字段,因此不会生成迁移、不会存入表结构,DRF序列化器自然也读不到该字段。
你之前给Mixin继承models.Model后报MRO错误,是因为没有将Mixin标记为抽象模型,同时继承顺序有误。
正确实现方案
1. 调整模型Mixin定义
模型字段复用的Mixin必须继承models.Model,且显式设置Meta.abstract = True,同时注意多继承顺序:
from django.db import models class Base(models.Model): # 补充原代码遗漏的models前缀和必填的max_length参数 a = models.CharField(max_length=32) class Meta: abstract = True # 模型Mixin必须继承models.Model,且标记为抽象类 class Mixin(models.Model): b = models.CharField(max_length=32) class Meta: abstract = True # 核心配置:标记为抽象模型,不会生成单独表,规避MRO钻石继承问题 # 注意继承顺序:Mixin放在前面,基础抽象模型放在后面 class Concrete(Mixin, Base): c = models.CharField(max_length=32)
调整后执行python manage.py makemigrations和python manage.py migrate,就能看到b字段被正常加入Concrete对应的数据库表结构中。
2. 调整DRF序列化器配置
你之前的序列化器存在两个问题:基类没有继承模型序列化器、子类字段配置覆盖了父类配置,调整如下:
from rest_framework import serializers class BaseSerializer(serializers.ModelSerializer): class Meta: model = Base fields = ('a',) abstract = True class ConcreteSerializer(BaseSerializer): class Meta(BaseSerializer.Meta): model = Concrete # 拼接父类字段+当前新增字段,符合DRY原则无需重复定义 fields = BaseSerializer.Meta.fields + ('b', 'c',)
3. 视图集小修正
你原代码中ConcreteViewSet的Meta类继承对象写错了,调整为继承自身基类即可,不影响字段显示:
from rest_framework import viewsets class BaseViewSet(viewsets.ModelViewSet): # 此处定义通用@actions方法 class Meta: abstract = True class ConcreteViewSet(BaseViewSet): serializer_class = ConcreteSerializer class Meta(BaseViewSet.Meta): abstract = False
内容的提问来源于stack exchange,提问作者Salvatore Iovene
相关产品推荐
相关产品推荐

