如何在Django端修改字段名适配Bootstrap Autocomplete?
问题:Django端字段映射适配Bootstrap Autocomplete格式
我需要为字段实现自动补全功能,但不清楚行业标准的实现方式。Bootstrap Autocomplete要求特定的字段命名格式(至少"text"字段是硬编码的),示例格式如下:
[ { "value": 1, "text": "Google Cloud Platform" }, { "value": 2, "text": "Amazon AWS" }, { "value": 3, "text": "Docker" }, { "value": 4, "text": "Digital Ocean" } ]
请问如何在Django端将['id','provider']字段名转换/映射为['value','text']?
我的现有代码如下:
模型
class CloudProviders(models.Model): provider = models.CharField(max_length=255, blank=True, null=True) # id为默认字段 ...
序列化器
class CloudProvidersAutocompleteSerializer(serializers.HyperlinkedModelSerializer): class Meta: model = CloudProviders fields = ['id','provider']
视图
class CloudProvidersAutocomplete(viewsets.ModelViewSet): model = CloudProviders serializer_class = CloudProvidersAutocompleteSerializer def get_queryset(self): query= self.request.query_params.get('search') if query : data = CloudProviders.objects.filter(provider__contains=query) return data
更新:我已有一个解决方案,但不确定是否规范:
# 模型 class CloudProviders(models.Model): provider = models.CharField(max_length=255, blank=True, null=True) # id为默认字段 def _getProvider (self): return self.provider text = property(_getProvider ) ...
推荐的规范实现方式
1. 序列化器字段重命名(最推荐)
直接在序列化器里定义字段别名,无需修改模型,完全符合分层设计思想,不会影响其他接口:
class CloudProvidersAutocompleteSerializer(serializers.ModelSerializer): value = serializers.IntegerField(source='id') text = serializers.CharField(source='provider') class Meta: model = CloudProviders fields = ['value', 'text']
通过source参数指定原始字段名,序列化器会自动映射成value和text返回,是最干净的实现方式。
2. 模型中添加@property简化写法
你的现有方案是可行的,但可以用@property装饰器简化代码,同时补充value字段的映射:
class CloudProviders(models.Model): provider = models.CharField(max_length=255, blank=True, null=True) @property def text(self): return self.provider @property def value(self): return self.id
这种方式适合所有使用该模型的接口都需要value和text字段的场景,但如果只有自动补全接口需要,会额外增加模型属性,需根据实际情况选择。
3. 视图层手动转换(不推荐)
如果不想改动序列化器和模型,也可以在视图返回时手动转换字段名,但这种方式代码冗余,维护性差,不推荐:
class CloudProvidersAutocomplete(viewsets.ModelViewSet): model = CloudProviders serializer_class = CloudProvidersAutocompleteSerializer def get_queryset(self): query = self.request.query_params.get('search') return CloudProviders.objects.filter(provider__contains=query) if query else CloudProviders.objects.all() def list(self, request, *args, **kwargs): response = super().list(request, *args, **kwargs) # 遍历转换字段名 response.data = [{'value': item['id'], 'text': item['provider']} for item in response.data] return response
这种方式需要手动处理数据结构,后续如果序列化器字段变化,这里也要同步修改,容易出错。
内容的提问来源于stack exchange,提问作者StJoesy
相关产品推荐
相关产品推荐

