I wanted to create a model to store settings:
# name: string
# value: string
# desccription
# Example:
{
"name": "currency.symbol",
"value": "€",
"description": "String to be attached at the end of some purchased values"
}
So I crated the model like this:
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__'
This was working fine with settings like theme
, language
but now I though I also want to have a structure, like currency.name
or currency.symbol
and I am getting a 404 error because of the dot .
using this paths:
<base_path>/api/v1/admin/setting/Theme/ # works
<base_path>/api/v1/admin/setting/currency.symbol/ # returns 404
I don't think is relevant, because I am getting the same from a curl, but I tried this in Angular
where I have my FE and did not make any difference:
const url = this.hostname + '/api/v1/admin/setting/' + encodeURI(element.name) + '/';
Is there an option to keep using the name as primary key and not having to switch to a new autoincremental pk?
Update:
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)),
]