Django REST, несколько наборов запросов за один GET
У меня есть следующие две модели:
models.py:
from django.contrib.auth.models import User
# Create your models here.
class Project(models.Model):
id = models.AutoField(db_column = 'db_ID', primary_key = True)
name = models.CharField(max_length=500, default = None)
descriptor = models.CharField(max_length = 1000, null = True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
db_table = 'projects'
def __str__(self):
return self.name
class Userproject(models.Model):
id = models.AutoField(db_column = 'db_ID', primary_key = True)
user = models.ForeignKey(User, on_delete= models.SET_NULL, null = True)
project = models.ForeignKey('Project', on_delete = models.SET_NULL, null = True)
created_at = models.DateTimeField(auto_now_add=True, null=True)
updated_at = models.DateTimeField(auto_now=True, null = True)
class Meta:
db_table = 'UserProjects'
def __str__(self):
return self.id
Поле Userprojects 'user' и 'project' указывают на Usermodel и Projectmodel выше.
Сейчас у меня такой вид:
class GetUserDataByNameView(
APIView,
):
def get(self, request, username):
if User.objects.filter(username = username).exists():
uid = User.objects.get(username = username).id
queryset = Userproject.objects.filter(user_id = uid)
readSerializer = GetUserDataSerializer(queryset, many = True)
return Response(readSerializer.data)
else:
return Response({"status": "error", "data":"no user with this username"}, status = 200)
и эти сериализаторы
from rest_framework import serializers
from .models import Project
from .models import Userproject
class ProjectSerializer(serializers.ModelSerializer):
name = serializers.CharField(max_length = 500, required = True)
descriptor = serializers.CharField(max_length = 1000, default = None)
class Meta:
model = Project
fields = ['name','descriptor',]
class UserprojectSerializer(serializers.ModelSerializer):
class Meta:
model = Userproject
fields = '__all__'
Итак, когда фронтенд передает имя пользователя в url, я отправляю обратно этот JSON:
[
{
"id": 16,
"created_at": "2021-10-20T16:05:03.757807Z",
"updated_at": "2021-10-20T16:05:03.762307Z",
"user": 3,
"project": 50
},
{
"id": 17,
"created_at": "2021-10-20T16:27:59.938422Z",
"updated_at": "2021-10-20T16:27:59.945439Z",
"user": 3,
"project": 51
}
]
Мне нужно включить ссылку на модель проекта в этот набор запросов, и я слышал, что метод Serializer - это то, что мне нужно. Но этот сериализатор не работает и выдает мне ошибку Attribute Error
class GetUserDataSerializer(serializers.ModelSerializer):
projects = serializers.SerializerMethodField()
class Meta:
model = Userproject
fields = '__all__'
def get_projects(self, obj):
data = ProjectSerializer(obj.Project.all(), many = True).data
return data
Ошибка заключается в следующем:
'Userproject' object has no attribute 'Project'
Я хочу добиться чего-то, что включает модель проекта с заданным ID проекта (в json он называется просто project), например, вот так:
{
"id": 17,
"created_at": "2021-10-20T16:27:59.938422Z",
"updated_at": "2021-10-20T16:27:59.945439Z",
"user": 3,
"project": 51
{
projectname : ...
projectdescriptor: ...
}
}
Я не уверен, правильно ли я понял ваш вопрос, но нижеприведенное должно направить вас на правильный путь.
Из вашего представления или в любом месте, где вы вызываете UserProfile, вы должны сделать это следующим образом,
#provided username is unique in your models.
class GetUserDataByNameView(
APIView,
):
def get(self, request, username):
try:
uid = User.objects.only('id').get(username=username)
except User.DoesNotExist:
return Response({"status": "error", "data":"no user with this username"}, status = 200)
queryset = Userproject.objects.select_related('project').filter(user_id=uid.id)
readSerializer = GetUserDataSerializer(queryset, many = True)
return Response(readSerializer.data)
Тогда в вашем сериализаторе вы должны сделать,
class GetUserDataSerializer(serializers.ModelSerializer):
projects = serializers.SerializerMethodField(source='get_projects')
class Meta:
model = Userproject
fields = '__all__'
def get_projects(self, obj):
serial_proj = ProjectSerializer(obj.project)
return serial_proj.data