让Django REST Framework的HyperlinkedModelSerializer识别非默认路由

时间:2014-06-01 23:41:27

标签: python django django-rest-framework

我正处于使用Django,Django REST Framework和SQL的项目的早期阶段。 我是DRF的新手。

我有一个模型可以跟踪为世界各地区运行不同服务器的游戏服务的用户信息(例如NA,EU等)。用户ID仅为每个区域唯一,但用户都使用相同的模型(表)存储。我在我的模型的Meta类中使用unique_together = ('user_id', 'region')来确保没有重复项。 请注意,因此,数据库中的PK与用户ID无关。

默认情况下,DRF会使用数据库的用户PK来创建端点,但我已将其更改为使用/users/na/123之类的系统来获取user_id = 123和{{{{{ 1}}(北美)。 urls.py中的代码片段如下:

region = 'na'

这些是通用视图(generics.ListAPIView和generics.RetrieveAPIView),尊重。

目前,我的其他观点都是ViewSets。

我建模的一件事是历史匹配数据,用户通过游戏模型与之相关,以跟踪参与比赛的人:

url(r'^users/(?P<region>.+)/$', UserList.as_view()),
url(r'^users/(?P<region>.+)/(?P<user_id>.+$)', UserDetail.as_view()),

我计划实施像我用户那样的游戏路线(同样,game_id只针对每个地区是唯一的)所以我可以class Game(models.Model): player_1 = models.ForeignKey(User) player_2 = models.ForeignKey(User)

我的问题是:

如何在API的游戏列表/详细信息视图中使用我已建立的/game/<region>/<game_id>路径获取指向用户的超链接?

目前,我的GameSerializer定义如下:

/user/<region>/<user_id>

当我将其更改为class GameSerializer(serializers.ModelSerializer): class Meta: model = Game exclude = ('id',) 时,在访问游戏终端时出现以下错误:

  

无法使用视图名称解析超链接关系的URL   &#34;用户细节&#34 ;.您可能未能在其中包含相关模型   您的API,或者HyperlinkedModelSerializer属性配置不正确   这个领域。

我认为这是因为我的用户端点的实现方式与预期不同(它无法知道我已经放弃了默认的PK索引方法并选择了自定义路由而不是lookup_field {1}},对吗?)

如何解决此问题?我愿意接受与DRF方面无关的建议,例如重构我的DB / Django模型,如果看起来我希望事情的方向是疯狂的(不想使用PK)。

2 个答案:

答案 0 :(得分:1)

经过几天阅读并以不同的方式思考问题之后,看起来Meta.unique_together有点像在SQL中表达复合键。这引出了我的解决方案:

https://groups.google.com/forum/#!topic/django-rest-framework/tHmEAzSNgG4

  

e.g。而不是使用这样的URL来识别员工:

     

api/1.3/employee/5/

     

我使用这样的网址:

     

api/1.3/company/23/employee/5/

     

我使用HyperlinkedModelSerializer来序列化这个模型。一世   找不到配置HyperlinkedIdentityField的方法   处理复合键(您只能指定一个lookup_field)   所以我用SerializerMethodField覆盖url,如下所示:

class EmployeeSerializer(serializers.HyperlinkedModelSerializer):
   url = serializers.SerializerMethodField('get_employee_detail_url')


   def get_employee_detail_url(self, obj):
       # generate the URL for the composite key
       ...
       return composite_key_url

仍在探索我的选择,但这看起来很干净。

答案 1 :(得分:0)

我今天刚遇到同样的问题。在浏览了Generic视图的Django-Rest-Framework文档后,我遇到了:

lookup_field - 应该用于执行单个模型实例的对象查找的模型字段。默认为&#39; pk&#39;。请注意,使用超链接API时,如果需要使用自定义值,则需要确保API视图和序列化程序类都设置了查找字段。

http://www.django-rest-framework.org/api-guide/generic-views

就我而言,我在models.py

中做到了这一点
class UserDetailView(generics.RetrieveAPIView):
    model = User
    serializer_class = UserSerializer
    lookup_field = "username"

......现在很可爱。希望有所帮助。