Skip to content

Update my fork #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Mar 25, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .pyup.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
search: False
schedule: "every two weeks"
requirements:
- requirements/requirements-codestyle.txt:
update: all
Expand Down
51 changes: 39 additions & 12 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
language: python
dist: xenial
sudo: required
cache: pip
# Favor explicit over implicit and use an explicit build matrix.
Expand All @@ -12,6 +13,10 @@ matrix:
- env: TOXENV=py35-django22-drfmaster
- env: TOXENV=py36-django22-drfmaster
- env: TOXENV=py37-django22-drfmaster
- env: TOXENV=py38-django22-drfmaster
- env: TOXENV=py36-django30-drfmaster
- env: TOXENV=py37-django30-drfmaster
- env: TOXENV=py38-django30-drfmaster

include:
- python: 3.6
Expand All @@ -21,50 +26,72 @@ matrix:

- python: 3.5
env: TOXENV=py35-django111-drf310
- python: 3.5
env: TOXENV=py35-django111-drf311
- python: 3.5
env: TOXENV=py35-django111-drfmaster
- python: 3.5
env: TOXENV=py35-django21-drf310
- python: 3.5
env: TOXENV=py35-django21-drf311
- python: 3.5
env: TOXENV=py35-django21-drfmaster
- python: 3.5
dist: xenial
env: TOXENV=py35-django22-drf310
- python: 3.5
dist: xenial
env: TOXENV=py35-django22-drf311
- python: 3.5
env: TOXENV=py35-django22-drfmaster

- python: 3.6
env: TOXENV=py36-django111-drf310
- python: 3.6
env: TOXENV=py36-django111-drf311
- python: 3.6
env: TOXENV=py36-django111-drfmaster
- python: 3.6
env: TOXENV=py36-django21-drf310
- python: 3.6
env: TOXENV=py36-django21-drf311
- python: 3.6
env: TOXENV=py36-django21-drfmaster
- python: 3.6
dist: xenial
env: TOXENV=py36-django22-drf310
- python: 3.6
dist: xenial
env: TOXENV=py36-django22-drf311
- python: 3.6
env: TOXENV=py36-django22-drfmaster
- python: 3.6
env: TOXENV=py36-django30-drf311
- python: 3.6
env: TOXENV=py36-django30-drfmaster

- python: 3.7
dist: xenial
sudo: required
env: TOXENV=py37-django21-drf310
- python: 3.7
dist: xenial
sudo: required
env: TOXENV=py37-django21-drf311
- python: 3.7
env: TOXENV=py37-django21-drfmaster
- python: 3.7
dist: xenial
sudo: required
env: TOXENV=py37-django22-drf310
- python: 3.7
dist: xenial
sudo: required
env: TOXENV=py37-django22-drf311
- python: 3.7
env: TOXENV=py37-django22-drfmaster
- python: 3.7
env: TOXENV=py37-django30-drf311
- python: 3.7
env: TOXENV=py37-django30-drfmaster

- python: 3.8
env: TOXENV=py38-django22-drf311
- python: 3.8
env: TOXENV=py38-django22-drfmaster
- python: 3.8
env: TOXENV=py38-django30-drf311
- python: 3.8
env: TOXENV=py38-django30-drfmaster

install:
- pip install tox
script:
Expand Down
2 changes: 2 additions & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ Adam Wróbel <https://adamwrobel.com>
Adam Ziolkowski <[email protected]>
Alan Crosswell <[email protected]>
Anton Shutik <[email protected]>
Boris Pleshakov <[email protected]>
Christian Zosel <https://zosel.ch>
David Vogt <[email protected]>
Greg Aker <[email protected]>
Expand All @@ -26,3 +27,4 @@ Stas S. <[email protected]>
Nathanael Gordon <[email protected]>
Charlie Allatson <[email protected]>
Joseba Mendivil <[email protected]>
Felix Viernickel <[email protected]>
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
Note that in line with [Django REST Framework policy](http://www.django-rest-framework.org/topics/release-notes/),
any parts of the framework not mentioned in the documentation should generally be considered private API, and may be subject to change.

## [3.1.0] - 2020-02-08

### Added

* Added support for Python 3.8
* Added support for Django REST framework 3.11
* Added support for Django 3.0

### Fixed

* Ensured that `409 Conflict` is returned when processing a `PATCH` request in which the resource object’s type and id do not match the server’s endpoint as outlined in [JSON:API](https://jsonapi.org/format/#crud-updating-responses-409) spec.
* Properly return parser error when primary data is of invalid type
* Pass instance to child serializers when using `PolymorphicModelSerializer`
* Properly resolve related resource type when using `PolymorphicModelSerializer`

## [3.0.0] - 2019-10-14

This release is not backwards compatible. For easy migration best upgrade first to version
Expand Down
6 changes: 3 additions & 3 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,9 @@ As a Django REST Framework JSON API (short DJA) we are trying to address followi
Requirements
------------

1. Python (3.5, 3.6, 3.7)
2. Django (1.11, 2.1, 2.2)
3. Django REST Framework (3.10)
1. Python (3.5, 3.6, 3.7, 3.8)
2. Django (1.11, 2.1, 2.2, 3.0)
3. Django REST Framework (3.10, 3.11)

We **highly** recommend and only officially support the latest patch release of each Python, Django and REST Framework series.

Expand Down
6 changes: 3 additions & 3 deletions docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@ like the following:

## Requirements

1. Python (3.5, 3.6, 3.7)
2. Django (1.11, 2.1, 2.2)
3. Django REST Framework (3.10)
1. Python (3.5, 3.6, 3.7, 3.8)
2. Django (1.11, 2.1, 2.2, 3.0)
3. Django REST Framework (3.10, 3.11)

We **highly** recommend and only officially support the latest patch release of each Python, Django and REST Framework series.

Expand Down
3 changes: 1 addition & 2 deletions docs/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -682,11 +682,10 @@ Also we can override `related_field` in the url. Let's say we want the url to be
dict to the class:
```python
field_name_mapping = {
'line_items': 'order_items'
'order_items': 'line_items'
}
```


### Working with polymorphic resources

Polymorphic resources allow you to use specialized subclasses without requiring
Expand Down
4 changes: 2 additions & 2 deletions example/api/resources/identity.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ def posts(self, request):
posts = [{'id': 1, 'title': 'Test Blog Post'}]

data = {
encoding.force_text('identities'): IdentitySerializer(identities, many=True).data,
encoding.force_text('posts'): PostSerializer(posts, many=True).data,
encoding.force_str('identities'): IdentitySerializer(identities, many=True).data,
encoding.force_str('posts'): PostSerializer(posts, many=True).data,
}
return Response(utils.format_field_names(data, format_type='camelize'))

Expand Down
23 changes: 23 additions & 0 deletions example/migrations/0008_labresults.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Generated by Django 3.0.3 on 2020-02-06 10:24

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
('example', '0007_artproject_description'),
]

operations = [
migrations.CreateModel(
name='LabResults',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('date', models.DateField()),
('measurements', models.TextField()),
('research_project', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='lab_results', to='example.ResearchProject')),
],
),
]
7 changes: 7 additions & 0 deletions example/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,13 @@ class ResearchProject(Project):
supervisor = models.CharField(max_length=30)


class LabResults(models.Model):
research_project = models.ForeignKey(
ResearchProject, related_name='lab_results', on_delete=models.CASCADE)
date = models.DateField()
measurements = models.TextField()


class Company(models.Model):
name = models.CharField(max_length=100)
current_project = models.ForeignKey(
Expand Down
10 changes: 10 additions & 0 deletions example/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
Comment,
Company,
Entry,
LabResults,
Project,
ProjectType,
ResearchProject,
Expand Down Expand Up @@ -303,11 +304,20 @@ class Meta:


class ResearchProjectSerializer(BaseProjectSerializer):
# testing exclusive related field on inherited polymorphic model
lab_results = relations.ResourceRelatedField(many=True, read_only=True)

class Meta:
model = ResearchProject
exclude = ('polymorphic_ctype',)


class LabResultsSerializer(serializers.ModelSerializer):
class Meta:
model = LabResults
fields = ('date', 'measurements')


class ProjectSerializer(serializers.PolymorphicModelSerializer):
included_serializers = {
'project_type': ProjectTypeSerializer,
Expand Down
2 changes: 1 addition & 1 deletion example/tests/test_format_keys.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ def test_camelization(self):
'data': [
{
'type': 'users',
'id': encoding.force_text(user.pk),
'id': encoding.force_str(user.pk),
'attributes': {
'firstName': user.first_name,
'lastName': user.last_name,
Expand Down
30 changes: 24 additions & 6 deletions example/tests/test_model_viewsets.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ def test_key_in_list_result(self):
'data': [
{
'type': 'users',
'id': encoding.force_text(user.pk),
'id': encoding.force_str(user.pk),
'attributes': {
'first-name': user.first_name,
'last-name': user.last_name,
Expand Down Expand Up @@ -72,7 +72,7 @@ def test_page_two_in_list_result(self):
'data': [
{
'type': 'users',
'id': encoding.force_text(user.pk),
'id': encoding.force_str(user.pk),
'attributes': {
'first-name': user.first_name,
'last-name': user.last_name,
Expand Down Expand Up @@ -112,7 +112,7 @@ def test_page_range_in_list_result(self):
'data': [
{
'type': 'users',
'id': encoding.force_text(users[0].pk),
'id': encoding.force_str(users[0].pk),
'attributes': {
'first-name': users[0].first_name,
'last-name': users[0].last_name,
Expand All @@ -121,7 +121,7 @@ def test_page_range_in_list_result(self):
},
{
'type': 'users',
'id': encoding.force_text(users[1].pk),
'id': encoding.force_str(users[1].pk),
'attributes': {
'first-name': users[1].first_name,
'last-name': users[1].last_name,
Expand Down Expand Up @@ -157,7 +157,7 @@ def test_key_in_detail_result(self):
expected = {
'data': {
'type': 'users',
'id': encoding.force_text(self.miles.pk),
'id': encoding.force_str(self.miles.pk),
'attributes': {
'first-name': self.miles.first_name,
'last-name': self.miles.last_name,
Expand Down Expand Up @@ -185,6 +185,24 @@ def test_patch_requires_id(self):

self.assertEqual(response.status_code, 400)

def test_patch_requires_correct_id(self):
"""
Verify that 'id' is the same then in url
"""
data = {
'data': {
'type': 'users',
'id': self.miles.pk + 1,
'attributes': {
'first-name': 'DifferentName'
}
}
}

response = self.client.patch(self.detail_url, data=data)

self.assertEqual(response.status_code, 409)

def test_key_in_post(self):
"""
Ensure a key is in the post.
Expand All @@ -193,7 +211,7 @@ def test_key_in_post(self):
data = {
'data': {
'type': 'users',
'id': encoding.force_text(self.miles.pk),
'id': encoding.force_str(self.miles.pk),
'attributes': {
'first-name': self.miles.first_name,
'last-name': self.miles.last_name,
Expand Down
17 changes: 17 additions & 0 deletions example/tests/test_parsers.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,20 @@ def test_parse_invalid_data(self):

with self.assertRaises(ParseError):
parser.parse(stream, None, self.parser_context)

def test_parse_invalid_data_key(self):
parser = JSONParser()

string = json.dumps({
'data': [{
'id': 123,
'type': 'Blog',
'attributes': {
'json-value': {'JsonKey': 'JsonValue'}
},
}]
})
stream = BytesIO(string.encode('utf-8'))

with self.assertRaises(ParseError):
parser.parse(stream, None, self.parser_context)
Loading