首页 > 解决方案 > 中间模式的 DRF 串行器字段

问题描述

我正在制作应用程序来控制学生的存在。我有 4 个模型:

class Student(models.Model):
    name = models.CharField(max_length=70)

class Justification(models.Model):
    name = models.CharField(max_length=70)

class Session(models.Model):
    date = models.DateTimeField()
    present = models.ManyToManyField(Student)
    absences = models.ManyToManyField(Student, related_name='absences_set', through='Absence')

class Absence(models.Model):
    session = models.ForeignKey(Session, on_delete=models.CASCADE)
    atleta = models.ForeignKey(Student, on_delete=models.CASCADE)
    justification = models.ForeignKey(Justification, on_delete=models.CASCADE)

这些模型有更多的字段和不同的名称(我将名称翻译成英文),但基本上就是这样。

我正在使用 DRF 框架来制作 API。我已经为 设置了端点(和序列化器),Student但我不知道如何为模型制作序列化器。我希望它在有人发出以下请求时工作(我只需要一个端点来创建s)请求(我使用的是视图):JustificationAbsenceSessionPOSTSessionViewSet

{
    "date": "2019-02-01T10:08:52-02:00"
    "present": [
        2
    ],
    "absences": [
        {
          "student": 1,
          "justification": 1
        }
    ]
}

但是没有创建缺勤。我怎样才能使这种嵌套关系起作用?

ps:我只能提出一个请求,这就是为什么我不想提出一个请求来创建 a Session,然后再提出许多请求来创建Absences 并需要它们一起使用。如果有办法在同一个请求上创建所有这些(但不仅仅是同一个 JSON 对象)我可以接受这个解决方案

标签: pythondjangodjango-rest-framework

解决方案


如果我理解正确,您想在同一Season端点创建相应的缺勤和季节。我认为这两个模型都服务相同JustificationStudent它们只是学生的实例,如果我没有错的话,会保留学生的信息。所以我认为实际上没有必要保留Justfication模型。有需要的对应absences(学生)Season Model索取Justification。所以我的建议是保持模型结构像这样

class Student(models.Model):
    name = models.CharField(max_length=70)

class Session(models.Model):
    date = models.DateTimeField()
    present = models.ManyToManyField(Student)
    absences = models.ManyToManyField(Student, related_name='absences_set', through='Absence')

class Absence(models.Model):
    session = models.OneToOneField(Session, on_delete=models.CASCADE) # You can also keep Foreign-key
    atleta = models.ForeignKey(Student, on_delete=models.CASCADE)

然后有两种可能的方法来创建对应于SeasonPost 端点的 Absence 模型实例。我们可以覆盖的post方法SeasonViewset并在那里编写我们的逻辑,甚至可以覆盖SeasonSrealizer-create方法来做同样的事情。

我最好的选择是覆盖SeasonViewset. 这些可以像下面这样完成 - 重写 DRF CreateMixins

class SeasonViewSet(viewsets.ModelViewSet): 
     # your declare serializers and others thing

     def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        season_instance = self.perform_create(serializer)
        # creating Absence's instance and you need to add other fields as necessary
        Absence.objects.create(season=season_instance)
        headers = self.get_success_headers(serializer.data)

        return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)

推荐阅读