Search code examples
pythondjangodjango-signals

django post_save: update_or_create not working


class SubjectSectionTeacher(models.Model):
    Education_Levels = models.ForeignKey(EducationLevel, related_name='+', on_delete=models.CASCADE, blank=True)
    Courses = models.ForeignKey(Course, related_name='+', on_delete=models.CASCADE, null=True, blank=True)
    Sections = models.ForeignKey(Section, related_name='+', on_delete=models.CASCADE, null=True)




class StudentsEnrollmentRecord(models.Model):
    Student_Users = models.ForeignKey(StudentProfile, related_name='students', on_delete=models.CASCADE, null=True)
   Courses = models.ForeignKey(Course, related_name='+', on_delete=models.CASCADE, null=True, blank=True)
    Section = models.ForeignKey(Section, related_name='+', on_delete=models.CASCADE, null=True, blank=True)
    Education_Levels = models.ForeignKey(EducationLevel, related_name='+', on_delete=models.CASCADE, blank=True,



class StudentsEnrolledSubject(models.Model):
        Students_Enrollment_Records = models.ForeignKey(StudentsEnrollmentRecord, related_name='+',
                                                        on_delete=models.CASCADE, null=True)
        Subject_Section_Teacher = models.ForeignKey(SubjectSectionTeacher, related_name='+', on_delete=models.CASCADE,
                                                    null=True,blank=True)      

    @receiver(post_save, sender=StudentsEnrollmentRecord)
            def create(sender, instance, created, *args, **kwargs):
                teachers = SubjectSectionTeacher.objects.filter(Sections=instance.Section,
                                                                Education_Levels=instance.Education_Levels,
                                                                Courses=instance.Courses)
            for each in teachers:
                if created or teachers.exists():
                    print("if")
                    StudentsEnrolledSubject.objects.create(
                        pk=each.id,
                        Students_Enrollment_Records=instance,
                        Subject_Section_Teacher=each

                    )

Inserting data is working perfectly but when I update the existing data it creates another record not update

note: I already tried this StudentsEnrolledSubject.objects.create and StudentsEnrolledSubject.objects.update_or_create, but it still the same result


Solution

  • Condition

    for each in teachers:
        if created or teachers.exists():
    

    is wrong, teachers.exists() will be always true, since you already iterate through teachers.

    Another problem is, that signal functions shouldn't be an instance/class method - move it outside of your model. Currently the sender parameter would actually be self and so on, so created would be wrong as well. (or give it a @staticmethod decorator)

    Since you want to create the record only during StudentsEnrollmentRecord creation, you should handle the created parameter at the beginning of the signal function - this also saves you some queries.

    Also, give your signal function a more meaningful name, maybe generate_subjects?

    So the signal could look like this

    @receiver(post_save, sender=StudentsEnrollmentRecord)
    def create(sender, instance, created, *args, **kwargs):
        if not created:
            return
        teachers = SubjectSectionTeacher.objects.filter(...)
        for each in teachers:
            StudentsEnrolledSubject.objects.create(...)
    
    
    class StudentsEnrolledSubject(models.Model):
       ...