真的很挣扎,看起来应该是非常直接的。基本上,我只是尝试与用户关联的产品,然后在FE上呈现每个产品的short_name
。
我有一张包含user_id
和prod_id
的表格。该表可能如下所示:
user_id | prod_id
-----------------
2 | 42
2 | 2
2 | 21
13 | 7
13 | 17
13 | 2
user_id
是models.ForeignKey
表的User
,prod_id
是models.ForeignKey
到Products
表。更好的是,这是模型:
# ./home/models.py
from django.contrib.auth import get_user_model
from django.db import models
User = get_user_model()
class Product(models.Model):
id = models.AutoField(primary_key=True)
code = models.CharField(unique=True, max_length=16)
name = models.CharField(max_length=255, blank=True, null=True)
short_name = models.CharField(max_length=128)
updated = models.DateTimeField(blank=True, null=True)
created = models.DateTimeField(blank=True, null=True)
def __str__(self):
return self.short_name
class Meta:
db_table = 'Product'
class UserToProduct(models.Model):
user = models.ForeignKey(User, related_name='user_name', db_column='user_id', null=True)
prod = models.ForeignKey(Product, related_name='prod_name', db_column='prod_id', null=True)
class Meta:
db_table = 'User_to_Product'
unique_together = ('user', 'prod')
应该发生的是React前端基于谁登录到Django / DRF后端发送user_id
。这种情况发生得很好。以下是相关视图:
# ./home/views.py
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.status import HTTP_200_OK, HTTP_400_BAD_REQUEST
from rest_framework.views import APIView
from .serializers import GetProductSerializer
from .models import Home
class GetHomeAPIView(APIView):
permission_classes = [IsAuthenticated]
def post(self, request, *args, **kwargs):
serializer = GetProductSerializer(data=request.data)
if serializer.is_valid(raise_exception=True):
return Response(serializer.data, status=HTTP_200_OK)
return Response(serializer.errors, status=HTTP_400_BAD_REQUEST)
从那里,它应该只是拉出与它们相关的产品列表,然后从short_name
模型中读取Product
,或者实际上只是我可以解析{{}的对象1}}。
这是序列化器:
short_name
此特定变体会导致:# ./home/serializers.py
from rest_framework.serializers import (
IntegerField,
ModelSerializer,
SerializerMethodField,
StringRelatedField,
)
from .models import *
class GetProductSerializer(ModelSerializer):
prod_name = StringRelatedField(many=True, required=False)
product = SerializerMethodField('get_products')
class Meta:
model = UserToProduct
fields = ('user', 'prod', 'prod_name')
def get_products(self, obj):
products = UserToProduct.objects.filter(user=data['user'])
return products
。
将NameError: name 'data' is not defined
更改为:
get_products()
这导致:# for testing reasons
products = UserToProduct.objects.filter(user=2)
无论如何,我花了更多时间在这上面,而不是承认。这是一些非常基本的东西。我尝试过几十种变体。我将继续努力并发布我尝试过的内容和错误。
此外,这是我引用的文档,我已阅读了数十次:
http://www.django-rest-framework.org/api-guide/relations/
http://www.django-rest-framework.org/tutorial/5-relationships-and-hyperlinked-apis/
参考了无数其他有关这方面的问题/答案而且没有工作。
编辑:可能已经尝试了几十件事情,最终能够从服务器获得序列化响应;但是,它没有引入KeyError: 'prod_name'
。我只做了一些修改:
short_name
# ./home/models.py
class Product(models.Model)
...
users = models.ManyToManyField(User, through='UserToProduct')
另外,需要注意的是将# ./home/serializers.py
class GetProductSerializer(ModelSerializer):
user = IntegerField() # have to do this otherwise it returns the username and not the id
prod = SerializerMethodField()
class Meta:
model = UserToProduct
fields = [
'user',
'prod',
]
def get_prod(self, obj):
prod = UserToProduct.objects.filter(user=obj['user']).values('prod')
print(prod)
return prod
留作:
get_prod()
结果:prod = UserToProduct.objects.filter(user=obj['user'])
。但是,它会列出TypeError: Object of type 'UserToProduct' is not JSON serializable
中的short_name
。
答案 0 :(得分:0)
好的,终于认为我搞定了。虽然速度非常慢,但需要大约5秒才能返回真正看起来不对的信息。这对于数据量来说太长了。
无论如何,这是让它为我工作的原因:
# ./home/serializers.py
class GetProductSerializer(ModelSerializer):
prod = CharField() # otherwise it was using prod_id number
class Meta:
model = UserToProduct
fields = [
'prod'
]
UserToProduct.objects.filter(user=user).prefetch_related('prod')
比我尝试的方式更简单...刚刚解决速度问题。
编辑:由于这篇SO帖子的帮助,修正了速度问题:
Optimizing database queries in Django REST framework
将我的查询修改为以下内容:
setOpacityTo(value: number, duration: number)
它从4.75秒下降到1.5秒。绮山楂。