Skip to content

Commit

Permalink
Merge branch 'release/0.8.3'
Browse files Browse the repository at this point in the history
  • Loading branch information
pavlov99 committed Apr 8, 2015
2 parents 820653c + e40993a commit 27fa050
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 13 deletions.
4 changes: 4 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
2015-04-08 Kirill Pavlov <kirill.pavlov@phystech.edu>

* Add Partial form support for PUT request

2015-03-26 Kirill Pavlov <kirill.pavlov@phystech.edu>

* Version 0.8.2, add atomic transactions support for post and put. If
Expand Down
2 changes: 1 addition & 1 deletion jsonapi/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
""" JSON:API realization."""
__version = (0, 8, 2)
__version = (0, 8, 3)

__version__ = version = '.'.join(map(str, __version))
__project__ = PROJECT = __name__
42 changes: 31 additions & 11 deletions jsonapi/resource.py
Original file line number Diff line number Diff line change
Expand Up @@ -226,22 +226,42 @@ def update_delete_queryset(cls, queryset, **kwargs):
return queryset

@classmethod
def get_form(cls, fields=None):
""" Create Partial Form based on given fields.
def get_form(cls):
""" Create Partial Form based on given fields."""
if cls.Meta.form:
return cls.Meta.form

meta_attributes = {"model": cls.Meta.model, "fields": '__all__'}
Form = type('Form', (ModelForm,), {
"Meta": type('Meta', (object,), meta_attributes)
})
return Form

@classmethod
def get_partial_form(cls, Form, fields):
""" Get partial form based on original Form and fields set.
:param Form: django.forms.ModelForm
:param list fields: list of field names.
"""
meta_attributes = {"model": cls.Meta.model}
meta_attributes["fields"] = '__all__'
if not fields:
return Form

if fields is not None:
meta_attributes["fields"] = fields
meta_attributes = dict(fields=fields)

Form = type('Form', (ModelForm,), {
"Meta": type('Meta', (object,), meta_attributes)
# NOTE: if Form was created automatically, it's Meta is inherited from
# object already, double inheritance raises error. If form is general
# ModelForm created by user, it's Meta is not inherited from object and
# PartialForm creation raises error.
meta_bases = (Form.Meta,)
if not issubclass(Form.Meta, object):
meta_bases += (object,)

PartialForm = type('PartialForm', (Form,), {
"Meta": type('Meta', meta_bases, meta_attributes)
})
return Form
return PartialForm

@classmethod
def _get_include_structure(cls, include=None):
Expand Down Expand Up @@ -343,7 +363,7 @@ def post(cls, request=None, **kwargs):
for item in items:
if 'links' in item:
item.update(item.pop('links'))
Form = cls.Meta.form or cls.get_form()
Form = cls.get_form()
form = Form(item)
forms.append(form)

Expand Down Expand Up @@ -414,7 +434,7 @@ def put(cls, request=None, **kwargs):
for item in items:
if 'links' in item:
item.update(item.pop('links'))
Form = cls.Meta.form or cls.get_form(item.keys())
Form = cls.get_partial_form(cls.get_form(), item.keys())
instance = objects_map[item["id"]]
form = Form(item, instance=instance)
forms.append(form)
Expand Down
9 changes: 9 additions & 0 deletions tests/testapp/forms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from django import forms

from .models import PostWithPicture


class PostWithPictureForm(forms.ModelForm):
class Meta:
model = PostWithPicture
fields = "__all__"
4 changes: 4 additions & 0 deletions tests/testapp/resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
from jsonapi.resource import Resource
from jsonapi.api import API

from .forms import PostWithPictureForm

api = API()


Expand Down Expand Up @@ -35,8 +37,10 @@ class Meta:
class PostWithPictureResource(Resource):
class Meta:
model = 'testapp.PostWithPicture'
allowed_methods = 'GET', 'PUT'
fieldnames_include = 'title_uppercased',
fieldnames_exclude = 'title',
form = PostWithPictureForm


@api.register
Expand Down
20 changes: 19 additions & 1 deletion tests/testapp/tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import json
import unittest

from ..models import Author, Post
from ..models import Author, Post, PostWithPicture
from ..urls import api

User = get_user_model()
Expand Down Expand Up @@ -575,6 +575,24 @@ def test_update_models_save_error_atomic(self):
self.assertEqual(
set(Author.objects.values_list("name", flat=True)), {'name'})

def test_update_partial(self):
post = mixer.blend('testapp.postwithpicture', title="title")
response = self.client.put(
'/api/postwithpicture/{}'.format(post.id),
json.dumps({
"data": [{
"id": post.id,
"title": "new title",
}],
}),
content_type='application/vnd.api+json',
HTTP_ACCEPT='application/vnd.api+json'
)

self.assertEqual(response.status_code, 200)
post = PostWithPicture.objects.get()
self.assertEqual(post.title, "new title")

def test_delete_model(self):
author = mixer.blend("testapp.author")
response = self.client.delete(
Expand Down

0 comments on commit 27fa050

Please sign in to comment.