MrOldSir
MrOldSir

Reputation: 726

DestroyAPIView by several conditions

I have data models like:

from django.db import models


class Student(models.Model):
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
    email = models.EmailField()

    def __str__(self):
        return self.first_name + ' ' + self.last_name


class Course(models.Model):
    name = models.CharField(max_length=255)
    description = models.TextField()
    start_date = models.DateField(null=True)
    end_date = models.DateField(null=True)

    def __str__(self):
        return self.name


class CourseParticipant(models.Model):
    course = models.ForeignKey(Course, related_name='courses', on_delete=None)
    student = models.ForeignKey(Student, related_name='students', on_delete=None)
    completed = models.BooleanField(null=True, default=False)

    def __str__(self):
        return self.course

I have some serializer like:

class AssignStudentToCourseSerializer(serializers.ModelSerializer):
    class Meta:
        model = CourseParticipant
        fields = ('id', 'student', 'course')

class UnassignedStudentFromCourseSerializer(serializers.ModelSerializer):
    class Meta:
        model = CourseParticipant
        fields = ('student_id', 'course_id')

I have views for it

class AssignStudentToCourse(generics.CreateAPIView):
    serializer_class = AssignStudentToCourseSerializer


class UnassignedStudentFromCourse(generics.DestroyAPIView):
    serializer_class = UnassignedStudentFromCourseSerializer
    queryset = CourseParticipant.objects.all()

I have a table CourseParticipant with some records

-------------------------------------------
| id         | course_id   | student_id   |
|------------|-------------|--------------|
| 1          |      2      |     2        |
| 2          |      3      |     2        |
| 3          |      2      |     3        |
| 4          |      2      |     4        |
-------------------------------------------

I need to delete records from this table by course_id and student_id. Now, use DestroyAPIView I can delete a record by id, but it's not done the right way. How I can delete record from my table by several condition?

Upvotes: 2

Views: 2552

Answers (2)

Ryan H.
Ryan H.

Reputation: 7854

I had a similar case in which I wanted to send a DELETE method to an API endpoint and have the backend determine individual objects to delete. You can use DestroyAPIView and override the destroy method to achieve this.

class StudentApiView(generics.DestroyAPIView):
    queryset = Student.objects.all()

    def destroy(self, request, *args, **kwargs):
        # Do logic here to get `course_participant` to delete, then
        course_participant.delete()

        # Don't return super().destroy(request, *args, **kwargs)
        return Response(status=status.HTTP_204_NO_CONTENT)

Upvotes: 0

sachin mathew
sachin mathew

Reputation: 1457

with DestroyAPIView you can only delete the instance you are calling using the specific url

If you want to delete the CourseParticipant by calling student url

first create a view to get the student instance and get its related object and then delete it

class StudentApiView(generics.RetrieveAPIView):
    queryset = Student.objects.all()


    def get(self, request, *args, **kwargs):
        print(self.get_object(),)
        instance = self.get_object()
        course_participant_obj = CourseParticipant.objects.get(student=instance)
        course_participant_obj.delete()
        return Response('deleted', )

Upvotes: 2

Related Questions