中间模式的 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。我已经为 StudentJustificationAbsence 设置了端点(和序列化程序),但我无法弄清楚如何为 Session 模型制作序列化程序。我希望当有人发出以下POST(我只需要一个端点来创建Session)请求时它起作用(我正在为视图使用ViewSet):

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

但缺席不是创造的。如何使此嵌套关系正常工作?

ps:我只能提出一个请求

,这就是为什么我不想提出一个请求来创建Session然后提出许多请求来创建Absence并一起需要它们。如果有办法在同一请求(但不仅是相同的 JSON 对象)上创建所有这些,我对此解决方案没问题

如果我

理解正确,您想在同一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)

然后有两种可能的方法来创建与 Post 端点对应的缺席模型实例Season。我们可以覆盖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)

最新更新