Как разместить данные во встроенном документе с помощью Mongoengine REST

Я пытаюсь использовать Django с mongoengine для создания API.

Пока я могу получить объекты и удалить их. но когда я хочу опубликовать некоторые данные. Допустим, студент + курс выдает ошибку:

type object 'Course' has no attribute 'objects'

Модели ан..

#Model.py


class Course(EmbeddedDocument): 
    course_name = StringField(max_length=200)
    course_fee = StringField(max_length=200)

class Student(Document):
    student_name = StringField(max_length=200)
    student_contactperson = StringField(max_length=200)
    student_adress = StringField(max_length=200)
    courses = ListField(EmbeddedDocumentField(Course))


#Serializers.py
class CourseSerializer(EmbeddedDocumentSerializer):
    class Meta:
        model = Course
        fields = ('course_name','course_fee')


class StudentSerializer(DocumentSerializer):
    courses = CourseSerializer(many=True)
    class Meta:
        model = Student
        fields = ('student_name','student_contactperson','student_adress','courses')
        depth = 2

    def create(self, validated_data):
        course_data = validated_data.pop('courses')
        student = Student.objects.create(**validated_data)
        Course.objects.create(student=student, **course_data)
        return student

#Views.py

class StudentViewSet(meviewsets.ModelViewSet):
    lookup_field = 'name'
    queryset = Student.objects.all().order_by('-date_joined')
    serializer_class = StudentSerializer

person shabir Sole    schedule 16.05.2019    source источник


Ответы (1)


Document представляет документ MongoDB (то есть запись в коллекции), класс Document привязан к конкретной коллекции. EmbeddedDocument представляет собой структуру, вложенную в Document.

Таким образом, по замыслу EmbeddedDocument не привязан ни к какой коллекции, если только вы не встроите его внутрь документа.

Это означает, что вы не можете запросить или сохранить класс EmbeddedDocument, вам нужно запросить/сохранить родительский документ.

Document.objects — это точка входа для запроса коллекции, она существует только в классах документов. Вы звоните Course.objects.create, но Course является EmbeddedDocument.

Я считаю, что вам нужно изменить свой код на следующий класс StudentSerializer (DocumentSerializer): ...

def create(self, validated_data):
    course_data = validated_data.pop('courses')
    course = Course(**course_data)    # assuming course_data is {course_name: ..., course_fee: ...}
    return Student.objects.create(courses=[course], **validated_data)
person bagerard    schedule 16.05.2019
comment
спасибо за Ваш ответ. Меня смущают курсы = CourseSerializer(many=True). Когда я устанавливаю значение False, он работает с вашим кодом, и новый документ будет создан, но в ответе нет информации о курсе (курсы: {}). когда я выбираю many=True, код не работает, но получил ошибку: ожидал список элементов, но получил тип \dict\.. - person shabir Sole; 16.05.2019
comment
Не могли бы вы уточнить, что вы подразумеваете под and use [] to add nested ? - person bagerard; 17.05.2019
comment
Согласно вашей модели, student.courses должен быть списком dict, но вместо этого вы публикуете простой dict. Что-то не так - person bagerard; 17.05.2019