【发布时间】:2016-05-15 12:14:38
【问题描述】:
我一直在用 Django 编写一个游戏选择风格的 webapp,最近决定用 DRF 将我的视图实现为 API 端点,以便在前端方法方面给我更多的灵活性。我的每个模型都有基本的序列化程序和视图集,我可以使用(优秀的)可浏览 API 正常浏览它们。以下是一对:
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
我一直在努力研究如何在 ViewSet 中表示它。使用常规的 Django 视图,很容易编写 get_object(或 get_list)以及 get_context_data,包括用户数据 + 来自数据库的任何其他所需对象,并将所有这些传递给模板。目前,上述(早期)API 端点版本如下所示:
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)
此代码有效,但仅返回有限的对象子集 - 单个用户工作表。我在这个 Viewset 中的目标是使用list() 返回给定联赛的所有比赛列表(只是用户表的集合),并使用retrieve() 给定联赛+周,但我不知道如何返回该数据。使用普通的 Django 上下文变量,您包含的额外数据可以以您喜欢的任何方式命名 - 使用 DRF 收集和返回任意数量的潜在不同对象的目标是如何实现的?编辑:这最初不是很清楚 - 我已经让嵌套表示工作,但我想知道是否有一种方法可以命名/标记不同的序列化对象,其方式是可以使用任何名称设置正常上下文中的信息
假设我想传递请求用户的序列化表格,以及他们的对手表格和所有其他球员表格,用于这个特定的联赛和一周。确定哪些属于用户,哪些属于他们的对手,哪些属于其他玩家的逻辑是否必须住在前端代码中?
另外,我将如何配置路由器以使 list() 方法始终需要 URL 参数(用于联赛)?每当我从
更改注册时router.register(r'matchup', MatchupViewset, base_name = 'matchup')
类似
router.register(r'matchup/(?P<league>[0-9]+)/$', MatchupViewset, base_name = 'matchup')
端点从可浏览的 API 根目录中消失。
【问题讨论】:
标签: python django django-rest-framework