简体   繁体   English

DRF串行器字段,用于中间模式

[英]DRF Serializer field for intermediate mode

I am making am app to control the presence of students. 我正在制作一个应用程序来控制学生的到场。 I have 4 models: 我有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)

The models have more fields and different names (I translated the names to English) but this is basically it. 这些模型具有更多的字段和不同的名称(我将名称翻译为英语),但是基本上就是这样。

I am using DRF framework to make an API. 我正在使用DRF框架制作API。 I have setup the endpoints (and serializers) for Student , Justification and Absence but I can't figure out how to make the serializer for the Session model. 我已经为StudentJustificationAbsence设置了端点(和序列化器),但是我不知道如何为Session模型制作序列化器。 I want it to work when someone makes the following POST (I only need an endpoint to create Session s) request (I am using a ViewSet for the view): 我希望它在有人发出以下POST (我只需要一个端点来创建Session )请求时ViewSet (我正在使用ViewSet作为视图):

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

But the absences are not created. 但是没有缺席是没有造成的。 How can I make this nested relationship work? 如何使这种嵌套关系起作用?

ps: I can only make one request that's why I don't want to make one request to create a Session and then many requests to create Absence s and need it all together. ps:我只能发出一个请求,这就是为什么我不想发出一个请求来创建Session ,然后又不想发出多个请求来创建Absence并一起需要它们的原因。 If there is a way to create all of them on the same request (but not only the same JSON object) I am okay with this solution 如果有一种方法可以在同一请求上创建所有这些对象(但不仅是同一JSON对象),我对此解决方案还可以

If i understand properly you want to create corresponding absences and season at same Season end-point. 如果我正确理解,您想在同一Season终点创建相应的缺勤和季节。 I think Justification and Student both model serve same, they are just student's instance and keep student information if i am not wrong. 我认为JustificationStudent两种模式服务相同,它们只是学生的实例,如果我没有记错的话,则保留学生的信息。 So i don't think there is actually any need to keep Justfication model. 因此,我认为实际上没有必要保留Justfication模型。 Corresponding absences ( students ) in Season Model need to ask for Justification . Season Model相应的absences (学生)需要Justification So my advice to keep model structure as like these 所以我建议保持像这样的模型结构

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)

And then there are two possible way to create Absence model instance corresponding to Season Post endpoint. 然后,有两种可能的方法来创建与Season Post端点相对应的“缺勤”模型实例。 We can overwrite the post method of SeasonViewset and write our logic there or even can overwrite the SeasonSrealizer-create method to do same. 我们可以覆盖SeasonViewsetpost方法并在其中编写逻辑,甚至可以覆盖SeasonSrealizer-create方法来执行此操作。

My preferable option is to overwrite post method of SeasonViewset . 我最好的选择是覆盖SeasonViewset post方法。 And these can be done as like following - over writing DRF CreateMixins 这些可以像下面那样完成-重写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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM