Skip to content

Commit

Permalink
Merge branch 'release/0.7.2'
Browse files Browse the repository at this point in the history
  • Loading branch information
pavlov99 committed Mar 6, 2015
2 parents d55bb20 + b3fdca1 commit e6ccdcf
Show file tree
Hide file tree
Showing 13 changed files with 176 additions and 4 deletions.
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, 7, 1)
__version = (0, 7, 2)

__version__ = version = '.'.join(map(str, __version))
__project__ = PROJECT = __name__
19 changes: 18 additions & 1 deletion jsonapi/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class Meta:
"""
from django.http import HttpResponse, HttpResponseNotAllowed
from django.shortcuts import render
import logging
import json
from .exceptions import JSONAPIError
Expand Down Expand Up @@ -116,7 +117,8 @@ def urls(self):
"""
from django.conf.urls import url
urls = [
url(r'^$', self.map_view),
url(r'^$', self.documentation),
url(r'^/map$', self.map_view),
]

for resource_name in self.resource_map:
Expand Down Expand Up @@ -183,6 +185,21 @@ def map_view(self, request):
response = json.dumps(resource_info)
return HttpResponse(response, content_type="application/vnd.api+json")

def documentation(self, request):
""" Resource documentation.
.. versionadded:: 0.7.2
Content-Type check
:return django.http.HttpResponse
"""
self.update_urls(request)
context = {
"resources": sorted(self.resource_map.items())
}
return render(request, "index.html", context)

def handler_view_get(self, resource, **kwargs):
items = json.dumps(
resource.get(**kwargs),
Expand Down
8 changes: 7 additions & 1 deletion jsonapi/model_inspector.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,12 @@ class Field(object):
('to_many', 'TO_MANY'),
)

def __init__(self, name, category, related_model=None):
def __init__(self, name, category, related_model=None, django_field=None):
self.name = name
self.related_model = related_model
self.category = category
self.is_bidirectional = None
self.django_field = django_field

@property
def query_name(self):
Expand Down Expand Up @@ -143,6 +144,7 @@ def _get_fields_own(cls, model):
Field(
name=field.name,
related_model=None,
django_field=field,
category=Field.CATEGORIES.OWN
) for field in model._meta.fields
if field.rel is None and (field.serialize or field.name == 'id')
Expand All @@ -155,6 +157,7 @@ def _get_fields_self_foreign_key(cls, model):
Field(
name=field.name,
related_model=field.rel.to,
django_field=field,
category=Field.CATEGORIES.TO_ONE
) for field in model._meta.fields
if field.rel and field.rel.multiple
Expand All @@ -174,6 +177,7 @@ def _get_fields_others_foreign_key(cls, model):
name=field.rel.related_name or "{}_set".format(
get_model_name(related_model)),
related_model=related_model,
django_field=field,
category=Field.CATEGORIES.TO_MANY
) for related_model in models.get_models()
if not related_model._meta.proxy
Expand All @@ -190,6 +194,7 @@ def _get_fields_self_many_to_many(cls, model):
Field(
name=field.name,
related_model=field.rel.to,
django_field=field,
category=Field.CATEGORIES.TO_MANY
) for field in model._meta.many_to_many
]
Expand All @@ -202,6 +207,7 @@ def _get_fields_others_many_to_many(cls, model):
name=field.rel.related_name or "{}_set".format(
get_model_name(related_model)),
related_model=related_model,
django_field=field,
category=Field.CATEGORIES.TO_MANY
) for related_model in models.get_models()
if related_model is not model
Expand Down
2 changes: 2 additions & 0 deletions jsonapi/resource.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,9 @@ def __new__(mcs, name, bases, attrs):
"Abstract model {} could not be resource".format(model))

cls.Meta.model_info = model_inspector.models[cls.Meta.model]
cls.Meta.default_form = cls.Meta.form or cls.get_form()

cls.Meta.description = cls.__doc__ or ""
return cls


Expand Down
5 changes: 5 additions & 0 deletions jsonapi/static/bootstrap.min.css

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions jsonapi/static/highlight.min.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions jsonapi/static/highlight.min.js

Large diffs are not rendered by default.

13 changes: 13 additions & 0 deletions jsonapi/static/main.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
aside {
float: left;
width: 220px;
margin-right: 20px;
display: block;
min-height: 1px;
}

#content {
float: left;
display: block;
width: 624px;
}
114 changes: 114 additions & 0 deletions jsonapi/templates/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
{% load staticfiles %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>API Documentation</title>
<link rel="stylesheet" href="{% static 'bootstrap.min.css' %}">
<link rel="stylesheet" href="{% static 'highlight.min.css' %}">
<link rel="stylesheet" href="{% static 'main.css' %}">

<script src="{% static 'highlight.min.js' %}"></script>
</head>
<body>
<div class="container">
<header>
<h1>API Documentation</h1>
</header>
<div>
<aside>
<nav class="nav-main">
<ul>
<li class="nav-header">Authentication</li>
<li class="nav-header">Resources</li>
{% for resource_name, resource in resources %}
<li>
<a href="#{{ resource_name }}">
{{ resource_name|capfirst }}
</a>
</li>
{% endfor %}
</ul>
</nav>
</aside>
<div id="content">
<h1>Getting Started</h1>
Generated date: {% now 'c' %}

<h1>Resources</h1>
{% for resource_name, resource in resources %}
<section id="{{ resource_name }}">
<h2 class="bg-primary">{{ resource_name|capfirst }}</h2>
{% if resource.Meta.description %}
<pre>{{ resource.Meta.description }}</pre>
{% endif %}
<table class="table table-bordered">
<tr>
<td>Location</td>
<td>{{ resource.Meta.api.api_url }}/{{ resource_name }}</td>
</tr>
<tr>
<td>Document Location</td>
<td>{{ resource.Meta.api.api_url }}/{{ resource_name }}/{id}</td>
</tr>
<tr>
<td>Allowed methods</td>
<td>{{ resource.Meta.allowed_methods }}</td>
</tr>
<tr>
<td>Authenticators</td>
<td>{{ resource.Meta.authenticators }}</td>
</tr>
</table>

<h3>Fields</h3>
<table class="table table-bordered">
<tr>
<th>Name</th>
<th>Type</th>
<th>Default</th>
<th>Description</th>
</tr>
{% for field in resource.Meta.model_info.fields_own %}
<tr>
<td>{{ field.name }}</td>
<td>{{ field.django_field.description }}</td>
{% if field.django_field.has_default %}
<td>{{ field.django_field.default }}</td>
{% else %}
<td></td>
{% endif %}
<td>{{ field.django_field.help_text }}</td>
</tr>
{% endfor %}
</table>

<h3>Form Fields</h3>
<table class="table table-bordered">
<tr>
<th>Name</th>
<th>Required</th>
<th>Description</th>
</tr>
{% for field_name, field in resource.Meta.default_form.base_fields.items %}
<tr>
<td>{{ field_name }}</td>
<td>{{ field.required }}</td>
<td>{{ field.help_text }}</td>
</tr>
{% endfor %}
</table>
<!-- <h3>Usage Examples</h3> -->
<!-- <h4>GET</h4> -->
<!-- <h5>Request</h5> -->
<!-- <h5>Response</h5> -->
</section>
{% endfor %}
</div>
</div>
</div>


<script>hljs.initHighlightingOnLoad();</script>
</body>
</html>
10 changes: 10 additions & 0 deletions tests/testapp/resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@

@api.register
class UserResource(Resource):

""" User Resource."""

class Meta:
model = settings.AUTH_USER_MODEL
authenticators = [Resource.AUTHENTICATORS.SESSION]
Expand All @@ -16,6 +19,13 @@ class Meta:

@api.register
class AuthorResource(Resource):

""" Author Resource.
Description for Author Resource.
"""

class Meta:
model = 'testapp.Author'
allowed_methods = 'GET', 'POST', 'PUT', 'DELETE'
Expand Down
2 changes: 1 addition & 1 deletion tests/testapp/settings/base.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import os.path
import django

BASE_DIR = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
STATIC_URL = '/static/'
Expand All @@ -18,6 +17,7 @@
'django.contrib.admin',
'django.contrib.messages',
'django.contrib.sessions',
'jsonapi',
'tests.testapp',
)
MIDDLEWARE_CLASSES = (
Expand Down
1 change: 1 addition & 0 deletions tests/testapp/settings/dev.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import django
from .base import *

INSTALLED_APPS += (
Expand Down
1 change: 1 addition & 0 deletions tests/testapp/settings/test.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import django
from .base import *

if django.VERSION[:2] < (1, 6):
Expand Down

0 comments on commit e6ccdcf

Please sign in to comment.