Django REST API endpoints URL paths
I have a Django 4.2 app with Postgres DB and REST API. My urls.py contains this path in urlpatterns:
path('create/<int:pk>/<str:name>/', ComponentCreate.as_view(), name='create-component')
ComponentCreate in views.py relates to a simple DB table (component) with id as integer primary key and name as the only other column.
views.py has:
class ComponentCreate(generics.CreateAPIView):
queryset = Component.objects.all(),
serializer_class = ComponentSerializer
lookup_field = "id"
models.py has:
class Component(models.Model):
id = models.IntegerField(primary_key=True)
name = models.CharField(max_length=255, blank=True, null=True)
class Meta:
managed = True
db_table = 'component'
serializers.py has:
class ComponentSerializer(serializers.ModelSerializer):
id = serializers.IntegerField()
name = serializers.CharField()
class Meta:
model = Component
fields = ('id', 'name')
I am trying to use the API to add a row to the component table using e.g. as below (where app is called SystemTestDB):
curl -X POST http://127.0.0.1:8000/SystemTestDB/create/2/whatever/
However this fails with response:
{"id":["This field is required."],"name":["This field is required."]}
I have other endpoints which do work correctly e.g. with path:
path('delete/<int:pk>/', ComponentDelete.as_view(), name='delete-component')
In that case evidently id is being passed via int:pk, whilst in the failing case neither id nor name are set in the Request.
Have I set the URL path incorrectly, or is there something wrong with model/view/serializer ?
Remove the custom fields, by this you make them mandatory:
class ComponentSerializer(serializers.ModelSerializer):
# id = serializers.IntegerField()
# name = serializers.CharField()
class Meta:
model = Component
fields = ('id', 'name')
or if you really want to customize, set required=False
[drf-doc]:
class ComponentSerializer(serializers.ModelSerializer):
id = serializers.IntegerField(read_only=True)
name = serializers.CharField(required=False)
class Meta:
model = Component
fields = ('id', 'name')
in the model you set the id
as AutoField
, or just hide it:
class Component(models.Model):
id = models.AutoField(primary_key=True)
# …