django rest框架更改主键使用唯一字段

时间:2014-03-10 14:46:10

标签: django django-rest-framework

我有一个名为GameProfile的模型,它与User模型是一对一的关系。我在所有设计中都使用了HyperlinkedModelSerializer

对于GameProfile,用户字段被认为是查询的主键,它是唯一的,但我没有将其设置为主键。有没有办法将django序列化程序的默认行为更改为指向user__id作为主键,并始终使用它来在详细信息视图中检索配置文件?

class GameProfileSerializer(serializers.HyperlinkedModelSerializer):
    """ 
    """
    user_pk = serializers.Field(source='user.id')

    class Meta:
        model = GameProfile


class GameProfileViewSet(viewsets.ModelViewSet):
    """
    """
    queryset = GameProfile.objects.all()
    serializer_class = GameProfileSerializer

    def get_queryset(self):
        """ get_queryset
        """
        queryset = super(GameProfileViewSet, self).get_queryset()
        if not queryset.exists():
            raise Http404
        if self.request.user.is_authenticated() and not self.request.user.is_superuser:
            return queryset.filter(user=self.request.user)
        return queryset

请提前告知,谢谢:)

3 个答案:

答案 0 :(得分:17)

假设您的GameProfile模型如下:

class GameProfile(models.Model)
    user = models.OneToOneField('User')

序列化器将是:

class GameProfileSerializer(serializers.HyperlinkedModelSerializer):
    user_id = serializers.Field(source='user.id')

    class Meta:
        model = GameProfile

正确设置视图上的.lookup_field属性:

    lookup_field = 'user_id'

网址将是:

/gameprofile/<user_id>

答案 1 :(得分:13)

为了使URL正常工作,您可能需要在ViewSet上添加lookup_field,而不仅仅是在序列化程序上。所以你会:

class GameProfileViewSet(viewsets.ModelViewSet):
    queryset = GameProfile.objects.all()
    serializer_class = GameProfileSerializer
    lookup_field = 'user__id'

在这种情况下,lookup_field使用双下划线符号而不是点符号(点在URL模式中的正则表达式中不起作用)。我无法获得@almalki@patsweet提议的解决方案。根据序列化程序上的documentation,“此选项[lookup_field]的值应与URL conf中的kwarg以及模型上的字段对应”,因此它可能不会不能使用RelatedFields。

答案 2 :(得分:1)

如果我正确理解你的问题,你需要一个像这样的网址结构:

/api/<GameProfile-resource>/<user-pk>

如果是这种情况,您应该检查lookup_field选项。 Link

您的Serializer类看起来像:

class GameProfileSerializer(serializers.HyperlinkedModelSerializer):
    """ 
    """
    user_pk = serializers.Field(source='user.id')

    class Meta:
        model = GameProfile
        lookup_field = 'user_pk'  # Might have to use 'user__id'