简体   繁体   中英

DRF Serializer field for intermediate mode

I am making am app to control the presence of students. I have 4 models:

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. 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. 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):

{
    "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. 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

If i understand properly you want to create corresponding absences and season at same Season end-point. I think Justification and Student both model serve same, they are just student's instance and keep student information if i am not wrong. So i don't think there is actually any need to keep Justfication model. Corresponding absences ( students ) in Season Model need to ask for 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. We can overwrite the post method of SeasonViewset and write our logic there or even can overwrite the SeasonSrealizer-create method to do same.

My preferable option is to overwrite post method of SeasonViewset . And these can be done as like following - over writing 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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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