Python Django Rest framework-更改hyperlinkedmodel序列化程序中的URL主机名
我有一个使用DRF1.8.x构建的Web服务,它主要是模型驱动的。我的目的是在响应中为所有外键字段提供绝对URL,这包括正确的主机名(网关主机名)。但是,由于该api位于nginx网关后面,因此修改了hostname字段,并且向序列化程序实例发送上下文['request']似乎没有帮助 到目前为止,我正在使用decorator修改主机名,并从基于版本的行为处理self-url字段,但foriegn键字段仍然显示为api主机名。下面是我的代码: 序列化程序.pyPython Django Rest framework-更改hyperlinkedmodel序列化程序中的URL主机名,python,django-models,django-rest-framework,Python,Django Models,Django Rest Framework,我有一个使用DRF1.8.x构建的Web服务,它主要是模型驱动的。我的目的是在响应中为所有外键字段提供绝对URL,这包括正确的主机名(网关主机名)。但是,由于该api位于nginx网关后面,因此修改了hostname字段,并且向序列化程序实例发送上下文['request']似乎没有帮助 到目前为止,我正在使用decorator修改主机名,并从基于版本的行为处理self-url字段,但foriegn键字段仍然显示为api主机名。下面是我的代码: 序列化程序.py class NodeSeriali
class NodeSerializer(serializers.HyperlinkedModelSerializer):
url = serializers.SerializerMethodField()
class Meta:
model = Node
fields = ('url', 'name', 'description', 'owner', 'address',
'created', 'updated', 'endpoint')
extra_kwargs= {
'endpoint': {'view_name': 'loadbalancerendpoint-detail'},
'owner': {'view_name': 'artifactowner-detail'}
}
@set_api_version_ref
def get_url(self, obj):
return self.context['request'].META.get('HTTP_REF')
装饰器-设置api版本
def set_api_version_ref(f):
@functools.wraps(f)
def wrapper(obj, ref):
base_href = obj.context['request'].META.get('PATH_INFO', None)
http_host = obj.context['request'].META.get('HTTP_X_HOST', None)
'''
Parse the incoming request URL to take API version in to a variable
'''
version_parse = re.search('\/myapi\/v(?P<version>(1(\.[0-1])?))\/\w+', base_href)
api_version = version_parse.group('version')
logger.debug("API Version detected: {}".format(api_version))
href_suffix = base_href+str(ref.id)+"/"
if http_host:
href = 'https://'+http_host+href_suffix
base_path = 'https://'+http_host+'/myapi/'+api_version+"/"
else:
href = href_suffix
base_path = '/myapi/v'+api_version+"/"
logger.debug("href assembled: {}".format(href))
obj.context['request'].META['API_VERSION'] = api_version
obj.context['request'].META['HTTP_REF'] = href
obj.context['request'].META['BASE_PATH'] = base_path
result = f(obj, ref)
return result
return wrapper
def set\u api\u version\u ref(f):
@functools.wrapps(f)
def包装(obj,ref):
base_href=obj.context['request'].META.get('PATH_INFO',无)
http_host=obj.context['request'].META.get('http_X_host',无)
'''
解析传入的请求URL以将API版本引入变量
'''
version\u parse=re.search('\/myapi\/v(?P(1(\.[0-1])?)\/\w+',base\u href)
api_version=version_parse.group('version'))
debug(“检测到的API版本:{}”。格式(API_版本))
href_suffix=base_href+str(ref.id)+“/”
如果http_主机:
href='https://'+http\u主机+href\u后缀
基本路径='https://'+http_主机+'/myapi/'+api_版本+“/”
其他:
href=href\u后缀
基本路径='/myapi/v'+api\u版本+“/”
logger.debug(“href汇编:{}”.format(href))
obj.context['request'].META['API_VERSION']=API_VERSION
obj.context['request'].META['HTTP_REF']=href
obj.context['request'].META['BASE\u PATH']=BASE\u PATH
结果=f(对象,参考)
返回结果
返回包装器
向相关的字段视图名称(loadbalancerendpoint detail、artifactowner detail等)传递额外的_Kwarg似乎会为其pk返回一个url,但我不知道如何在不使用装饰器的情况下修改其主机名,就像我为url字段所做的那样。非常感谢您的帮助,谢谢 可能重复的