Python 用Django REST Framework视图集表示多个对象/列表CRUD操作
我一直在用Django编写一个游戏挑选风格的webapp,最近决定用DRF将我的视图实现为API端点,以便在涉及前端方法时给我更多的灵活性。我的每个模型都有基本的序列化程序和视图集,我可以使用(优秀的)可浏览API正常浏览它们。以下是几点:Python 用Django REST Framework视图集表示多个对象/列表CRUD操作,python,django,django-rest-framework,Python,Django,Django Rest Framework,我一直在用Django编写一个游戏挑选风格的webapp,最近决定用DRF将我的视图实现为API端点,以便在涉及前端方法时给我更多的灵活性。我的每个模型都有基本的序列化程序和视图集,我可以使用(优秀的)可浏览API正常浏览它们。以下是几点: class SheetSerializer(serializers.HyperlinkedModelSerializer): user = UserSerializer(read_only = True) league = LeagueSeriali
class SheetSerializer(serializers.HyperlinkedModelSerializer):
user = UserSerializer(read_only = True)
league = LeagueSerializer(read_only = True)
picks = serializers.HyperlinkedRelatedField(
source='pick_set',
many=True,
view_name='pick-detail',
read_only = True
)
class Meta:
model = Sheet
fields = ('url', 'id', 'league_week', 'user', 'league', 'picks')
class GameSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Game
fields = ('url', 'home_team', 'away_team', 'week', 'home_team_score', 'away_team_score')
class PickSerializer(serializers.HyperlinkedModelSerializer):
sheet = SheetSerializer()
game = GameSerializer()
class Meta:
model = Pick
fields = ('url', 'sheet', 'amount', 'spread', 'pick_type', 'pick_team', 'game')
使用相应的视图集:
class PickViewset(viewsets.ModelViewSet):
queryset = Pick.objects.all()
serializer_class = PickSerializer
class GameViewset(viewsets.ModelViewSet):
queryset = Game.objects.all()
serializer_class = GameSerializer
class SheetViewset(viewsets.ModelViewSet):
queryset = Sheet.objects.all()
serializer_class = SheetSerializer
我目前遇到的问题是如何表示比单个对象或同类型对象CRUD操作列表更复杂的端点。例如,我目前有一个用于匹配的常规Django视图,它拉取用户表(拾取集合)、另一个用户表,并显示相互嵌套的拾取。我还计划在同一页面上显示来自其他用户的其他数据,无论他们属于哪个联盟。vanilla Django中用户+对手数据的实现如下所示:
class MatchupDetail(DetailView):
template_name = 'app/matchups.html'
context_object_name = 'pick_sheet'
def get_object(self):
#logic to find and return object
def get_opponent(self,username,schedule,week, **kwargs):
#logic to find and return the opponent in the matchup
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
#logic to pull the opponents details and set them in the context
class MatchupViewset(viewsets.ReadOnlyModelViewSet):
serializer_class = SheetSerializer
def get_queryset(self):
user = self.request.user
return Sheet.objects.filter(user=self.request.user)
def list(self, request, format=None):
sheets = self.get_queryset()
serializer = SheetSerializer(sheets, many=True, context={'request': request})
return Response(serializer.data)
def retrieve(self, request, pk, format=None):
sheet = Sheet.objects.get(user=self.request.user, league_week=pk)
serializer = SheetSerializer(sheet, context={'request':request})
return Response(serializer.data)
我一直在努力研究如何在视图集中表示这一点。使用常规的Django视图,很容易编写get_对象(或get_列表)以及get_context_数据,包括用户数据和数据库中任何其他所需对象,并将所有这些传递给模板。目前,上述的(早期)API端点版本如下所示:
class MatchupDetail(DetailView):
template_name = 'app/matchups.html'
context_object_name = 'pick_sheet'
def get_object(self):
#logic to find and return object
def get_opponent(self,username,schedule,week, **kwargs):
#logic to find and return the opponent in the matchup
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
#logic to pull the opponents details and set them in the context
class MatchupViewset(viewsets.ReadOnlyModelViewSet):
serializer_class = SheetSerializer
def get_queryset(self):
user = self.request.user
return Sheet.objects.filter(user=self.request.user)
def list(self, request, format=None):
sheets = self.get_queryset()
serializer = SheetSerializer(sheets, many=True, context={'request': request})
return Response(serializer.data)
def retrieve(self, request, pk, format=None):
sheet = Sheet.objects.get(user=self.request.user, league_week=pk)
serializer = SheetSerializer(sheet, context={'request':request})
return Response(serializer.data)
这段代码可以工作,但只返回有限的对象子集-单个用户表。我在这个视图集中的目标是返回一个列表,其中列出了list()。使用普通的Django上下文变量,您包含的额外数据可以以您喜欢的任何方式命名-使用DRF收集和返回任意数量的潜在不同对象的目标是如何实现的?编辑:这一点一开始不是很清楚-我已经使用了嵌套表示,但我想知道是否有一种方法可以命名/标记不同的序列化对象,使正常上下文中的信息可以用任何名称设置
假设我想通过请求用户的序列表,以及他们的对手表和这个特定联赛和本周的所有其他球员表。逻辑会决定哪些属于用户,哪些属于他们的对手,哪些是其他玩家必须生活在前端代码中吗
另外,如何配置路由器,使list()方法始终需要URL参数(用于联盟)?任何时候我从
router.register(r'matchup', MatchupViewset, base_name = 'matchup')
差不多
router.register(r'matchup/(?P<league>[0-9]+)/$', MatchupViewset, base_name = 'matchup')
router.register(r'matchup/(?P[0-9]+)/$),MatchupViewset,base_name='matchup')
端点将从可浏览的API根目录中消失
使用DRF收集和返回任意数量的潜在不同对象的目标是如何实现的
我不确定这里到底是什么问题。我想你会想要嵌套的表示,这是解释过的
端点将从可浏览的API根目录中消失
这是因为可浏览的API不知道如何解决额外的Kwarg。因为没有url匹配,他不会显示链接你是对的-我认为这个问题不清楚。我有嵌套表示,但我想知道是否有某种方法可以像使用上下文
变量那样标记序列化对象的实例。关于URL问题:它不知道如何解析额外的参数是有道理的,我只是不知道如何指定它们是预期的。由于路由器处理视图集URL,是否应该以某种方式在视图集中指定一个额外的URL?尽管嵌套路由不被视为最佳做法,但您可能希望了解这一点。感谢链接!我很确定我对路由器/URL问题的想法是错误的——视图集使很多事情变得简单,但我将进行重构,将每个视图集方法显式地映射到一个具体的视图,然后手动注册每个URL。或者使用常规的基于APIView的类而不是视图集,因为这里似乎缺少一些东西。再次感谢!