Django Rest Framework:带有序列化程序的ForeignKey

时间:2018-07-19 08:04:25

标签: django rest django-rest-framework

我有两个简单表,带有一个ForeignKey。我想使用外键检索表中的数据:

CREATE TABLE `firerisk_reminder` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` longtext NOT NULL,
  PRIMARY KEY (`id`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `firerisk_remindertype` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(45) NOT NULL,
  `reminder_id` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `name` (`name`),
  KEY `firerisk_remindertyp_reminder_id_03340ffc_fk_firerisk_` (`reminder_id`),
  CONSTRAINT `firerisk_remindertyp_reminder_id_03340ffc_fk_firerisk_` FOREIGN KEY (`reminder_id`) REFERENCES `firerisk_reminder` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

因此,我在Django中的模型:

class Reminder(models.Model):
    name = models.TextField(default='')
    report = models.OneToOneField(Report, related_name='reminder', on_delete=models.PROTECT)

    def __str__(self):
        return self.name

class ReminderType(models.Model):
    name = models.CharField(max_length=45, unique=True)
    reminder = models.ForeignKey(Reminder,related_name='reminderstype',on_delete=models.PROTECT)

在DRF中,我正在使用像这样的序列化器:

class ReminderTypeSerializer(serializers.ModelSerializer):
    id = serializers.IntegerField(read_only=True)
    name = serializers.CharField()

    class Meta:
        model = ReminderType
        fields = ('id', 'name')
        ordering = ('name',)

class ReminderSerializer(serializers.ModelSerializer):
    remindertypes = ReminderTypeSerializer(read_only=True)
    id = serializers.IntegerField(read_only=True)
    name = serializers.CharField()

    class Meta:
        model = Reminder
        ordering = ('name',)
        fields = ('id', 'name', 'remindertypes')

最后,我的ViewSet:

class ReminderTypeViewSet(viewsets.ModelViewSet):
    serializer_class = ReminderTypeSerializer
    queryset = ReminderType.objects.all().order_by('name')
    # Authentification !
    permission_classes = (IsAuthenticated,)
    # Only 'get' method
    http_method_names = ['get']

class ReminderViewSet(viewsets.ModelViewSet):
    serializer_class = ReminderSerializer
    queryset = Reminder.objects.all().order_by('name')
    # Authentification !
    permission_classes = (IsAuthenticated,)
    # Only 'get' method
    http_method_names = ['get']

当我反向调用串行器时,如下所示:

class ReminderTypeSerializer(serializers.ModelSerializer):
    reminder = ReminderSerializer(read_only=True)
    id = serializers.IntegerField(read_only=True)
    name = serializers.CharField()

我有数据,但是这种关系对我来说没有意义(提醒类型):

[
    {
        "id": 1,
        "name": "yyyyyyyy",
        "reminder": {
            "id": 1,
            "name": "First report test"
        }
    },
    {
        "id": 2,
        "name": "xxxxxxxx",
        "reminder": {
            "id": 1,
            "name": "First report test"
        }
    }
]

我已经测试了其他一些关系(嵌套,相关等),但均未成功。

你能帮我吗? 谢谢 F。

1 个答案:

答案 0 :(得分:2)

您已将related_name='reminderstype'设置为提醒字段,因此在序列化程序中应为reminderstype = ReminderTypeSerializer(read_only=True, many=True)

class ReminderSerializer(serializers.ModelSerializer):
    reminderstype = ReminderTypeSerializer(read_only=True, many=True)
    id = serializers.IntegerField(read_only=True)
    name = serializers.CharField()

    class Meta:
        model = Reminder
        ordering = ('name',)
        fields = ('id', 'name', 'reminderstype')

remindertypes = ReminderTypeSerializer(read_only=True, source='reminderstype')

class ReminderSerializer(serializers.ModelSerializer):
    remindertypes = ReminderTypeSerializer(read_only=True, source='reminderstype', many=True)

如果需要获取related_name的所有相关提醒类型,则应在序列化程序中使用ReminderSerializer

请注意添加many=True以序列化对象列表。