我的问题是,是否有可能在序列化器中添加HyperlinkedRelatedField以仅获取基类的属性。例如:
我想要一个这样的json:
{
"modules": [
{
"moduleName": "M1: Fundamentos Técnicos",
"moduleDetails": "Bla bla bla.",
"moduleID": 0,
"userScore": 3,
"slides": [
{
"slideType": "Content",
"slideID": 0
},
{
"slideType": "Minigame1",
"slideID": 1
},
{
"slideType": "Video",
"slideID": 6
}
]
}
]
}
在这里,Slide是基类,Video和Minigame是子类。 可以吗?是否可以为每张幻灯片的网址添加一个HyperlinkedRelatedField?。
谢谢!
更新!
这是我的模特
class Module(TimeStampedModel):
moduleID = models.AutoField(primary_key=True)
moduleName = models.CharField(
max_length=100,
verbose_name='Nombre del modulo')
moduleDetails = models.TextField(verbose_name='Detalle')
moduleBullet1 = models.CharField(max_length=100, verbose_name='Punto 1')
moduleBullet2 = models.CharField(max_length=100, verbose_name='Punto 2')
moduleBullet3 = models.CharField(max_length=100, verbose_name='Punto 3')
moduleImageURL = models.ImageField(
upload_to="modulos", verbose_name='Imagen')
userScore = models.PositiveSmallIntegerField(
default=0, verbose_name='Score de usuario')
class Slide(TimeStampedModel):
CONTENT = 'Content'
MINIGAME = 'Minigame'
VIDEO = 'Video'
SLIDE_TYPE_CHOICES = (
(CONTENT, 'Contenido'),
(MINIGAME, 'Minigame'),
(VIDEO, 'Video'),
)
slideType = models.CharField(
max_length=20,
choices=SLIDE_TYPE_CHOICES,
default=CONTENT,
)
slideID = models.AutoField(primary_key=True)
slideOrder = models.PositiveSmallIntegerField(
verbose_name='Orden de visualizacion')
module = models.ForeignKey(Module, on_delete=models.CASCADE,
related_name="%(app_label)s_%(class)s_related",
related_query_name="%(app_label)s_%(class)ss",)
class Meta:
abstract = True
class VideoContent(Slide):
videoURL = models.URLField(verbose_name='URL de video')
class Minigame(Slide):
timeToFail=models.PositiveSmallIntegerField()
在我的serializers.py中,我想要这样的东西:
class SlideSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Slide
fields = ('url', 'slideType', 'slideID')
class ModuleSerializer(serializers.ModelSerializer):
slides = SlideSerializer(many=True, read_only=True)
class Meta:
model = Module
fields = ('moduleID', 'moduleName', 'moduleDetails', 'moduleImageURL', 'userScore', 'slides')
我的view.py
class ModuleViewSet(viewsets.ModelViewSet):
"""
This viewset automatically provides `list`, `create`, `retrieve`,
`update` and `destroy` actions.
"""
queryset = Module.objects.all()
serializer_class = ModuleSerializer
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
class SlideViewSet(viewsets.ModelViewSet):
"""
This viewset automatically provides `list`, `create`, `retrieve`,
`update` and `destroy` actions.
"""
queryset = Slide.objects.all()
serializer_class = SlideSerializer
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
Slide.Objects引发错误,AttributeError:类型对象'Slide'没有属性'objects'
答案 0 :(得分:1)
您不能查询抽象基类。 Slice是一个抽象类,您不能在queryset = Slide.objects.all()
中使用SlideViewSet
,因为抽象模型不是实际的数据库对象,因此无法查询。
您必须在抽象继承之间进行选择,在这种情况下,两个类之间没有数据库关系,或者在多表继承之间进行选择,这使每个查询的数据库关系都以效率为代价(额外的数据库联接)。
class Slide(TimeStampedModel):
CONTENT = 'Content'
MINIGAME = 'Minigame'
VIDEO = 'Video'
SLIDE_TYPE_CHOICES = (
(CONTENT, 'Contenido'),
(MINIGAME, 'Minigame'),
(VIDEO, 'Video'),
)
slideType = models.CharField(
max_length=20,
choices=SLIDE_TYPE_CHOICES,
default=CONTENT,
)
slideID = models.AutoField(primary_key=True)
slideOrder = models.PositiveSmallIntegerField(
verbose_name='Orden de visualizacion')
module = models.ForeignKey(Module, on_delete=models.CASCADE,
related_name="%(app_label)s_%(class)s_related",
related_query_name="%(app_label)s_%(class)ss",)
class VideoContent(Slide):
videoURL = models.URLField(verbose_name='URL de video')
class Minigame(Slide):
timeToFail=models.PositiveSmallIntegerField()
现在,您的视图集:
class SlideViewSet(viewsets.ModelViewSet):
"""
This viewset automatically provides `list`, `create`, `retrieve`,
`update` and `destroy` actions.
"""
queryset = Slide.objects.all()
serializer_class = SlideSerializer
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
Documentation on multi-table inheritance:
多表继承使用隐式的OneToOneField来链接 孩子和父母,可以从父母下移到 孩子
希望这可以清除一切。