我是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'
感谢您的帮助!
答案 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)