Используйте один и тот же класс сериализатора, но с другим действием в представлении в среде Django rest

#django #api #django-rest-framework #primary-key #django-serializer

Вопрос:

У меня есть представление набора моделей, в котором различные таможенные функции определяются в зависимости от требований. Мне нужно написать другую функцию get, в которой я хочу использовать тот же класс сериализатора. Но поле, которое я определил в классе сериализатора в pkfield, но для функции get, я хочу, чтобы оно было строковым полем, а не полем pk. Как этого добиться??

Кроме того, я определил глубину=1, что также не работает.

 class Class(TimeStampAbstractModel):  teacher = models.ForeignKey(  Teacher,  on_delete=models.CASCADE,  null=True,  related_name="online_class",  )  subject = models.ForeignKey(  Subject,  on_delete=models.SET_NULL,  null= True,  related_name= "online_class",  )  students_in_class = models.ManyToManyField(Student, related_name="online_class")  

Мое мнение:

 class ClassView(viewsets.ModelViewSet):  queryset = Class.objects.all()  serializer_class = ClassSerializer  serializer_action_classes = {  'add_remove_students': AddStudentstoClassSerializer,  'get_all_students_of_a_class': AddStudentstoClassSerializer,  }   def get_serializer_class(self):   """  returns a serializer class based on the action  that has been defined.  """  try:  return self.serializer_action_classes[self.action]  except (KeyError, AttributeError):  return super(ClassView, self).get_serializer_class()    def add_remove_students(self, request, *args, **kwargs):  """   serializer class used is AddStudentstoClassSerializer  """  def get_all_students_of_a_class(self,request,pk=None):  """  for this I function too, I want to use the same AddStudentstoClassSerializer class but   there is a problem. The field students_in_class is already defined as pkfield, whereas I  want to use it as a stringfields in the response of this function  """"  

Мой сериализатор:

 class AddStudentstoClassSerializer(serializers.ModelSerializer):  students_in_class = serializers.PrimaryKeyRelatedField(  many=True, queryset=Student.objects.all()  )   class Meta:  model = Class  fields = ["students_in_class"]  depth = 1   def update(self, instance, validated_data):  slug = self.context["slug"]  stu = validated_data.pop("students_in_class")  /................other codes....../  return instance  

Здесь мы видим, что класс student_in_class определен как pkfield, что нормально при использовании api обновления, но когда я хочу использовать api get и позвонить get_all_students_of_a_class , я хочу, чтобы поле было строковым полем или каким-либо другим полем. Как это сделать? Тоже depth= 1 тоже не работает.

Обновить:

Выполните следующие действия, но все еще не работает:

 def to_representation(self, instance):  rep = super().to_representation(instance)  # rep["students_in_class"] = instance.students_in_class  rep['students_in_class'] = StudentSerializer(instance.students_in_class).data  return rep  class StudentSerializer(serializers.ModelSerializer):  user = serializers.PrimaryKeyRelatedField(read_only=True)  class Meta:  model = Student  fields = ['user', 'college_name', 'address']  

что я получил в ответе, так это

 {  "students_in_class": {} }  

это пустой диктант. что нужно сделать!

Ответ №1:

Вы можете переопределить to_representation свой метод следующим образом.

 class AddStudentstoClassSerializer(serializers.ModelSerializer):  students_in_class = serializers.PrimaryKeyRelatedField(  many=True, queryset=Student.objects.all()  )   class Meta:  model = Class  fields = ["students_in_class"]    def to_representation(self, instance):  data = {  "students_in_class": # Write your logic here  }  return data   def update(self, instance, validated_data):  slug = self.context["slug"]  stu = validated_data.pop("students_in_class")  /................other codes....../  return instance  

Комментарии:

1. привет, Хасан, не могли бы вы, пожалуйста, проверить мой обновленный код. это не работает…

2. Измените свою строку на StudentSerializer(instance.students_in_class.all(), many=True).data

3. да, это сработало идеально, но вместо того, чтобы показывать все поля, могу ли я показывать конкретные поля только для студентов??

4. Вы можете написать новый сиализатор для этого или вот так instance.students_in_class.all().values('field1', 'field2') . Вы не будете сериализовываться для этого, если используете 2-й метод.