Django Rest Framework - 允许多种形式的查找值的视图集和重写方法

时间:2014-09-19 00:04:26

标签: python django django-rest-framework

我是DRF的新手,我在覆盖其方法方面遇到了麻烦。

我想允许Viewset接受相同查找值的两种不同形式,实质上是值的子字符串和完整字符串。

实施例。 位置和db pk,位置 .namespace.host.com

我能够成功覆盖get_object方法以允许GET请求的两个值,但如果我尝试提交POST来更新状态,那么它就不起作用了。由于它是一个pk,它会尝试创建一个pk = 位置的新数据库条目并失败。

我对改变kwarg感到高兴(当从DRF库运行csrf_exempt装饰器函数时,它会恢复到旧的kwarg)。

这样做的正确方法是什么?

from rest_framework import serializers
from myapp.apps.clusters.models import Status
from myapp.com.mixins.ViewSets import CreateUpdateListRetrieveViewSet
from django.http import Http404
from rest_framework.generics import GenericAPIView
from rest_framework.mixins import UpdateModelMixin


class StatusSerializer(serializers.ModelSerializer):
    class Meta:
        model = Status
        lookup_field = 'hostname'


class StatusViewSet(CreateUpdateListRetrieveViewSet):
    model = Status
    serializer_class = StatusSerializer
    lookup_field = 'hostname'

    def get_object(self, queryset=None):
        """
        Overrides the GenericView method to allow for both hostname and physname lookups

        i.e. physname (location) or full FQDN (location.namespace.host.com)

        Returns the object the view is displaying.
        """
        try:
            obj = GenericAPIView.get_object(self)
        except Http404:
            hostname = self.kwargs.get(self.lookup_field, None) + '.namespace.host.com'
            self.kwargs[self.lookup_field] = hostname
            obj = GenericAPIView.get_object(self)    
        return obj

    def update(self, request, *args, **kwargs):
        """ This doesn't play nice, overriding UpdateModelMixin's update """
        lookup_field = self.kwargs.get(self.lookup_field, None)
        if not '.namespace.host.com' in lookup_field
            hostname = lookup_field + '.namespace.host.com'
            self.kwargs['hostname'] = hostname
            kwargs['hostname'] = hostname
        return UpdateModelMixin.update(self, request, *args, **kwargs)

    def pre_save(self, obj):
        """ This was an attempt but the code is not currently hit """
        if not '.namespace.host.com' in self.kwargs['hostname']:
            self.kwargs['hostname'] = self.kwargs['hostname'] + '.namespace.host.com'

感谢您的帮助!

1 个答案:

答案 0 :(得分:-1)

为什么不覆盖视图集的__init__方法?

class StatusViewSet(CreateUpdateListRetrieveViewSet):
    model = Status
    serializer_class = StatusSerializer
    lookup_field = 'hostname'

    def __init__(self, *args, **kwargs):
        if 'hostname' in kwargs and '.namespace.host.com' not in kwargs['hostname']:
           kwargs['hostname'] = kwargs['hostname'] + '.namespace.host.com'
        super(StatusViewSet, self).__init(*args, **kwargs)