I took the Django drf-writable-nested package and made it a complete implementation called drf-writable-example by adding a bit of REST code (see below). (See drf-writable-nested page for the models and serializers.)
If I POST their JSON example (see below) twice, it creates every object in the JSON twice. So, two Site objects with url "http://google.com", two Avatar objects with image "image-1.png", etc.
How do I instead modify that code to create-or-update? That is, if the "http://google.com" site already exists, then just use it, and if the avatar object with "image-1.png" already exists, just use it, etc.?
Edit: It looks like this issue is about this question.
Edit 2: I thought POST/PUT might come up. Yes, I've read a number of blog posts and stackoverflow answers about POST and PUT. But I want update_or_create (also here and here), also called "upsert." That may not fit neatly into REST, but it's easier for the client, so that's what I want. POST is closer, because there may not be an object, so there's no id.
from rest_framework import routers, viewsets
from .serializers import UserSerializer
from .models import User
class UserModelViewSet(viewsets.ModelViewSet):
queryset = ExampleUser.objects.all()
serializer_class = UserSerializer
router = routers.DefaultRouter()
router.register(r'users', UserModelViewSet)
and registering that router to a URL.
Now I can POST the example from their docs (user-example.json) using httpie:
http POST http://localhost:8000/api/users/ \
< examples/user-example.json > my.log
If I POST that twice, I get two complete sets of stuff:
GET /api/users/
HTTP 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept
[
{
"pk": 1,
"profile": {
"pk": 1,
"sites": [
{
"pk": 1,
"url": "http://google.com"
},
{
"pk": 2,
"url": "http://yahoo.com"
}
],
"avatars": [
{
"pk": 1,
"image": "image-1.png"
},
{
"pk": 2,
"image": "image-2.png"
}
],
"access_key": {
"pk": 1,
"key": "key"
}
},
"username": "test"
},
{
"pk": 2,
"profile": {
"pk": 2,
"sites": [
{
"pk": 3,
"url": "http://google.com"
},
{
"pk": 4,
"url": "http://yahoo.com"
}
],
"avatars": [
{
"pk": 3,
"image": "image-1.png"
},
{
"pk": 4,
"image": "image-2.png"
}
],
"access_key": {
"pk": 2,
"key": "key"
}
},
"username": "test"
}
]