Jak zaktualizować wiele do wielu Django resztą?

głosy
2

Jak bym go o aktualizację wiele do wielu relacji w ramach Django REST?

Oto mój model.

class SchoolTeacher(AbstractBase):
    school = models.ForeignKey(School, on_delete=models.CASCADE, 
         related_name='teachers')
    user = models.ForeignKey(User, on_delete=models.CASCADE, 
         related_name='teacher_at',)
    subjects = models.ManyToManyField(SchoolSubject, 
        related_name='teachers')

Oto moja serializer:

class SchoolTeacherSerializer(serializers.ModelSerializer):
   ....
   def create(self, validated_data):
    school_class = validated_data.get('school_class', None)
    stream = validated_data.get('stream', None)

    school_teacher_model_fields = [
        f.name for f in SchoolTeacher._meta.get_fields()]
    valid_teacher_data = {
        key: validated_data[key]
        for key in school_teacher_model_fields
        if key in validated_data.keys()
    }
    subjects = valid_teacher_data.pop('subjects')
    teacher = SchoolTeacher.objects.create(**valid_teacher_data)

    for subject in subjects:
        teacher.subjects.add(subject)

    self.add_class_teacher(stream, school_class, teacher)

    return teacher

def update(self, instance, validated_data):
    subjects = validated_data.pop('subjects')
    school_class = validated_data.get('school_class', None)
    stream = validated_data.get('stream', None)
    teacher = instance

    for (key, value) in validated_data.items():
        setattr(teacher, key, value)

    for subject in subjects:
        teacher.subjects.add(subject)

    teacher.save()

    return teacher

Jak mogę uzyskać aktualizację subjects? Obecnie mogę tylko dodać, a nie usuwanie istniejących obiektów.

Utwórz 19/12/2018 o 14:09
źródło użytkownik
W innych językach...                            


2 odpowiedzi

głosy
0

Oto obejście. Żałuję jednak ktoś miałby zakładać lepszą odpowiedź. Chodzi o to, aby usunąć wszystkie przedmioty pierwszy następnie dodać je. Jednakże, ponieważ oczywiście nie możemy tego zrobić teacher.subjects.all().delete(), co możemy zrobić,

    for existing_subject in teacher.subjects.all():
        teacher.subjects.remove(existing_subject)

    for subject in subjects:
        teacher.subjects.add(subject)
Odpowiedział 19/12/2018 o 16:30
źródło użytkownik

głosy
0

Jak mówimy o wiele-do-wielu, oba obiekty muszą być utrwalone, zanim będzie można przypisać je do siebie.

Kiedy już, że można po prostu dodać jeden do dotyczącą gromadzenia drugiej, jak to (źródło: https://docs.djangoproject.com/en/2.1/topics/db/examples/many_to_many/ ):

a1 = Article(headline='Django lets you build Web apps easily')
a1.save()
p1 = Publication(title='The Python Journal')
p1.save()
a1.publications.add(p1)

Lub, w jednym kroku:

new_publication = a1.publications.create(title='Highlights for Children')

Nie dowiedziałem się, jak wyrazić „zawiera” jeszcze, ale następnym krokiem jest usunięcie obiektów, które nie są w nowej listy i dodać te, które są w nowe, ale nie stare liście. Prawdopodobnie bardziej efektywne z posortowanych list lub lepszych skrótów. Ale mój pyton nie jest wystarczająco dobre do tego jeszcze.

Odpowiedział 19/12/2018 o 14:55
źródło użytkownik

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more