python - 是否有解决方法在 django rest 中使用 URL 中具有特殊字符的字符串作为主键?
问题描述
我想创建一个模型来存储设置:
# name: string
# value: string
# desccription
# Example:
{
"name": "currency.symbol",
"value": "€",
"description": "String to be attached at the end of some purchased values"
}
所以我这样创建模型:
model.py
class Setting(models.Model):
"""Class to represent the global settings of the app that apply to all users."""
name = models.CharField(primary_key=True, max_length=100)
value = models.CharField(max_length=500, null=True)
description = models.TextField(null=True)
class Meta: # pylint: disable=too-few-public-methods
"""Class to represent metadata of the object."""
ordering = ['pk']
def __str__(self):
"""String for representing the Model object."""
return str(self.name)
view.py
class SettingViewset(viewsets.ModelViewSet): # pylint: disable=too-many-ancestors
"""API Endpoint to return the list of settings"""
queryset = Setting.objects.all()
serializer_class = SettingSerializer
pagination_class = None
permission_classes = [IsAuthenticated, IsAdminUserOrReadOnly]
serializer.py
class SettingSerializer(serializers.ModelSerializer):
"""Serializer for Setting."""
class Meta: # pylint: disable=too-few-public-methods
"""Class to represent metadata of the object."""
model = Setting
fields = '__all__'
这在像这样的设置下工作得很好theme
,language
但是现在我虽然也想要一个结构,像currency.name
or并且由于使用此路径currency.symbol
的点而出现 404 错误:.
<base_path>/api/v1/admin/setting/Theme/ # works
<base_path>/api/v1/admin/setting/currency.symbol/ # returns 404
我认为这无关紧要,因为我从卷曲中得到了同样的结果,但是我Angular
在我有我的 FE 的地方尝试了这个并且没有任何区别:
const url = this.hostname + '/api/v1/admin/setting/' + encodeURI(element.name) + '/';
是否可以选择继续使用名称作为主键而不必切换到新的自动增量 pk?
更新:
urls.py
"""
Django urls config for the app.
"""
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from rest_framework.authtoken.views import obtain_auth_token
from myapp import views
# Create a router and register our viewsets with it.
router = DefaultRouter()
# ...
router.register(r'admin/setting', views.SettingViewset)
# ...
urlpatterns = [
path('auth/', views.AuthToken.as_view(), name='auth'),
#...
path('', include(router.urls)),
]
解决方案
我发现了!事实上,默认情况下,«路由器将匹配包含除斜杠和句点字符之外的任何字符的查找值。»。您所要做的就是使用适当的正则表达式值扩展此默认值:
class SettingViewset(viewsets.ModelViewSet):
...
lookup_value_regex = '[\w.]+' # it should be enough :)
您也可以在另一个 stackoverflow 问题中看到这一点。
推荐阅读
- python - 找不到路径目录
- laravel - 在 Laravel 的 DataTable 中制作“导出到 excel”按钮
- javascript - 在 JS 中使用 XLSX 将 JSON 转换为 Excel 工作表时如何跳过一些键值对
- sql-server-2014 - 如何修复命名管道提供程序,错误:40 - 无法打开与 SQL Server 的连接?
- git - Git分支和合并:致命:拒绝合并不相关的历史
- python - 在 BeautifulSoup 中如何用某些词分割汤?
- android - IFrameCallback 不起作用
- r - 如果页面加载时间过长,在 RSelenium 中自动刷新网页?
- bash - Bash 脚本未在 Jenkins 中以状态码 1 退出
- ios - [iOS]更新分发证书时,IPA 文件是否仍然存在?