First I'll refactor your code and present the code examples. Afterwards I'll explain the changes.
foo_field = models.CharField(
# rest ...
You have set
foo_field as primary key. It is a bad practice to use strings (
VARCHAR) as primary key. It is highly recommended to use surrogate keys. This will be accomplished automatically by Django. It adds a field
id as primary key.
serializers.py will now work as it is. No changes are needed. Also the
views.py should work without changes. However I'll cover the option with
foo_field as primary key.
# rest ...
lookup_field = `foo_field`
You could also leave this out, but it is important to make some changes in your
In order for a web services to be ReSTful, they have to comply with the REST principles. One of the most important rules is that we shouldn't use a verb in the URL for describing the action. Another convention is that the resource name is used in plural to describe the collection and an identifier is used to access single resource.
Your resource is called example, therefore we use examples as collection name. Verbs like get or update have no place in the URL. The HTTP method is responsible for the proper action.
If you'd like to use
foo_field as primary key, then you have to change the the url for the update view:
This is because your
foo_field is a
CharField (or string), so the arguments passed to it should match any alphanumeric character (
\w) and the hyphen (
You can use
foo_field as named group in your url regex instead of
pk if you wish. Pay attention that you adapt that in your view, setting the correct values for
Again I'll strongly recommend to use surrogate keys and leave Django to accomplish this task.
Now you can understand why
CreateAPIView worked. They don't require an argument passed to the url and were properly called.
UpdateAPIView couldn't work because the matching url was accepting only digits and didn't match your primary key