получить все значения таблицы внешних ключей drf django - PullRequest
0 голосов
/ 23 марта 2020

У меня есть эти таблицы. Я хочу получить все поля таблицы учителя из школы. Текущий получает имя и поле сотрудника, указывающее на ключ учителя

class Teacher(models.Model):
      name = models.CharField(max_length=100)
      key = models.CharField(max_length=50,unique=True)
      value = models.CharField(max_length=50)
      def __str__(self):
          return self.name


class School(models.Model):
      name= models.CharField(max_length=100)
      employee = models.ForeignKey(Teacher, to_field="key",on_delete=models.CASCADE)

     def __str__(self):
         return self.name

serializers.py:

class TeacherSerializer(serializers.ModelSerializer):
     class Meta:
          model = Teacher
          fields = ('name','key','value')




class SchoolSerializer(serializers.ModelSerializer):
     teacher = TeacherSerializer(many=True, read_only=True)

    class Meta:
        model = School
        fields = ('name','employee','teacher')

views.py:

@api_view(['GET'])
def SchoolList(APIView):
    queryset = School.objects.all().values('name','employee','employee__value')
    asd=[]
    for sdf in queryset:
        asd.append(sdf)
    serialized_obj = SchoolSerializer(queryset,many=True)
    return HttpResponse(json.dumps(serialized_obj.data))

traceback:

  traceback (most recent call last):
  File "/home/tboss/Desktop/environment/tryme/venv/lib/python3.7/site-packages/django/core/handlers/exception.py", line 34, in inner
  response = get_response(request)
  File "/home/tboss/Desktop/environment/tryme/venv/lib/python3.7/site-packages/django/core/handlers/base.py", line 115, in _get_response
  response = self.process_exception_by_middleware(e, request)
  File "/home/tboss/Desktop/environment/tryme/venv/lib/python3.7/site-packages/django  /core/handlers/base.py", line 113, in _get_response
  response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/home/tboss/Desktop/environment/tryme/venv/lib/python3.7/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
  return view_func(*args, **kwargs)
  File "/home/tboss/Desktop/environment/tryme/venv/lib/python3.7/site-packages/django/views/generic/base.py", line 71, in view
  return self.dispatch(request, *args, **kwargs)
  File "/home/tboss/Desktop/environment/tryme/venv/lib/python3.7/site-packages/rest_framework/views.py", line 505, in dispatch
   response = self.handle_exception(exc)
  File "/home/tboss/Desktop/environment/tryme/venv/lib/python3.7/site-packages/rest_framework/views.py", line 465, in handle_exception
  self.raise_uncaught_exception(exc)
  File "/home/tboss/Desktop/environment/tryme/venv/lib/python3.7/site-packages/rest_framework/views.py", line 476, in raise_uncaught_exception
raise exc
  File "/home/tboss/Desktop/environment/tryme/venv/lib/python3.7/site-packages/rest_framework/views.py", line 502, in dispatch
  response = handler(request, *args, **kwargs)
  File "/home/tboss/Desktop/environment/tryme/venv/lib/python3.7/site-packages/rest_framework/decorators.py", line 50, in handler
return func(*args, **kwargs)
  File "/home/tboss/Desktop/environment/tryme/gama/main/views.py", line 20, in SchoolList
return HttpResponse(json.dumps(serialized_obj.data))
  File "/home/tboss/Desktop/environment/tryme/venv/lib/python3.7/site-packages/rest_framework/serializers.py", line 760, in data
ret = super().data
  File "/home/tboss/Desktop/environment/tryme/venv/lib/python3.7/site-packages/rest_framework/serializers.py", line 260, in data
self._data = self.to_representation(self.instance)
  File "/home/tboss/Desktop/environment/tryme/venv/lib/python3.7/site-packages/rest_framework/serializers.py", line 678, in to_representation
self.child.to_representation(item) for item in iterable
  File "/home/tboss/Desktop/environment/tryme/venv/lib/python3.7/site-packages/rest_framework/serializers.py", line 678, in <listcomp>
self.child.to_representation(item) for item in iterable
  File "/home/tboss/Desktop/environment/tryme/venv/lib/python3.7/site-packages/rest_framework/serializers.py", line 529, in to_representation
  ret[field.field_name] = field.to_representation(attribute)
  File "/home/tboss/Desktop/environment/tryme/venv/lib/python3.7/site-packages/rest_framework/relations.py", line 460, in to_representation
  return getattr(obj, self.slug_field)

AttributeError: у объекта 'str' нет атрибута 'key'

выход: он получает все поля учителя в каждом поле учителя

[{"name": "teacher", "employee": "subject", "teachers": [{"name": "pappu", "key": "subject", "value": "math"}, {"name":
"monu", "key": "another_subject", "value": "english"}]}, {"name": "teacher1", "employee": "another_subject", "teachers": [{"name": "pappu",
"key": "subject", "value": "math"}, {"name": "monu", "key": "another_subject", "value": "english"}]}]

Я ожидаю так:

[{"name": "teacher", "employee": "subject", "teachers": [{"name": "pappu", "key": "subject", "value": "math"}]}, {"name": "teacher1", "employee": "another_subject", "teachers": [{"name": "monu", "key": "another_subject", "value": "english"}]}]

1 Ответ

1 голос
/ 23 марта 2020

Я думаю, что ваша модель неправильная. У учителя должно быть имя поля employee, которое указывает на School, например:

class Teacher(models.Model):
      name = models.CharField(max_length=100)
      key = models.CharField(max_length=50,unique=True)  
      value = models.CharField(max_length=50)
      employee = models.ForeignKey(School, on_delete=CASCADE, related_name='teachers')

Затем вы можете сделать обратный запрос от школы к модели учителя, чтобы получить всех учителей. Например:

class SchoolSerializer(serializers.ModelSerializer):
     teachers = TeacherSerializer(many=True, read_only=True)  # using teachers due to `related_name` defined in employee field inside Teacher model

    class Meta:
        model = School
        fields = ('name','teachers')

Если ваша модель верна

Затем просто используйте:

class SchoolSerializer(serializers.ModelSerializer):
     employee = TeacherSerializer(read_only=True)

     class Meta:
        model = School
        fields = ('name', 'employee')

Обновление представления

Я думаю, что лучше обновите ваш взгляд так:

from rest_framework.response import Response

@api_view(['GET'])
def SchoolList(APIView):
    serialized_obj = SchoolSerializer(School.objects.all(),many=True)
    return Response(serialized_obj.data)
...