我正在制作应用程序来控制学生的存在。我有 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
、Justification
和 Absence
设置了端点(和序列化程序),但我无法弄清楚如何为 Session
模型制作序列化程序。我希望当有人发出以下POST
(我只需要一个端点来创建Session
)请求时它起作用(我正在为视图使用ViewSet
):
{
"date": "2019-02-01T10:08:52-02:00"
"present": [
2
],
"absences": [
{
"student": 1,
"justification": 1
}
]
}
但缺席不是创造的。如何使此嵌套关系正常工作?
ps:我只能提出一个请求,这就是为什么我不想提出一个请求来创建Session
然后提出许多请求来创建Absence
并一起需要它们。如果有办法在同一请求(但不仅是相同的 JSON 对象)上创建所有这些,我对此解决方案没问题
理解正确,您想在同一Season
终点创建相应的缺席和季节。我认为Justification
和Student
两种模型的服务相同,它们只是学生的实例,如果我没有错的话,它们会保留学生信息。所以我认为实际上没有必要保留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)