diff --git a/README.md b/README.md index 9520227ca0d30537d670ed6a480888b89d9e44e9..991ae21abbe28100f8c9c3f5fecbc99b29268506 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,7 @@ from djangoldp.models import Model class Todo(Model): name = models.CharField(max_length=255) deadline = models.DateTimeField() + ``` @@ -46,6 +47,7 @@ By default it will be "todos/" with an S for model called Todo <Model>._meta.container_path = "/my-path/" ``` + 3.2. Configure field visibility (optional) Note that at this stage you can limit access to certain fields of models using @@ -134,14 +136,14 @@ list of ForeignKey, ManyToManyField, OneToOneField and their reverse relations. In the following example, besides the urls `/members/` and `/members/<pk>/`, two other will be added to serve a container of the skills of the member: `/members/<pk>/skills/` and `/members/<pk>/skills/<pk>/` ``` - url(r'^members/', LDPViewSet.urls(model=Member, nested_fields=("skills",))), + <Model>._meta.nested_fields=["skills"] ``` From the 0.5 we added permissions check by default on every route, so you may encounter 400 errors code on your POST requests. You can disable those checks by specifying the permission_classes as an empty array in our URLs files. ``` -url(r'^posts/', LDPViewSet.urls(model=Post, permission_classes=(), filter_backends = ())), + <Model>.permissions_classes=[] ``` ## Custom Meta options on models @@ -150,6 +152,7 @@ url(r'^posts/', LDPViewSet.urls(model=Post, permission_classes=(), filter_backen ### auto_author This property allows to associate a model with the logged in user. + ```python class MyModel(models.Model): author_user = models.ForeignKey(settings.AUTH_USER_MODEL) @@ -158,7 +161,7 @@ class MyModel(models.Model): ``` Now when an instance of `MyModel` is saved, its `author_user` property will be set to the current user. -## permissions +## permissions_classes This allows you to add permissions for AnonymousUser, logged in user, author ... in the url: Currently, there are 3 choices : * ObjectPermission @@ -173,15 +176,17 @@ AnonymousReadOnly gives these permissions: * Logged in users: can read all posts + create new posts * Author: can read all posts + create new posts + update their own -``` -from django.conf.urls import url -from djangoldp.views import LDPViewSet -from djangoldp.permissions import AnonymousReadOnly +```python +from djangoldp.models import Model +from djangoldp.permissions import AnonymousReadonly + +class Todo(Model): + name = models.CharField(max_length=255) + deadline = models.DateTimeField() + + class Meta: + permission_classes = AnonymousReadonly -urlpatterns = [ - url(r'^projects/', ProjectViewSet.urls(permission_classes=(AnonymousReadOnly,))), - url(r'^customers/', LDPViewSet.urls(model=Customer)), -] ``` InboxPermissions is used for, well, notifications: @@ -194,15 +199,49 @@ from django.conf.urls import url from djangoldp.views import LDPViewSet from djangoldp.permissions import NotificationsPermissions -urlpatterns = [ - url(r'^projects/', ProjectViewSet.urls(permission_classes=(InboxPermissions,))), - url(r'^customers/', LDPViewSet.urls(model=Customer)), -] +class Project(Model): + name = models.CharField(max_length=255) + deadline = models.DateTimeField() + + class Meta: + permission_classes = InbcxPermissions + ``` Important note: If you need to give permissions to owner's object, don't forget to add auto_author in model's meta +### view_set +In case of custom viewset, you can use + +``` +from djangoldp.models import Model + +class Todo(Model): + name = models.CharField(max_length=255) + deadline = models.DateTimeField() + + class Meta: + view_set = TodoViewSet + +``` + +### container_path +See 3.1. Configure container path (optional) + +### serializer_fields +``` +from djangoldp.models import Model + +class Todo(Model): + name = models.CharField(max_length=255) + deadline = models.DateTimeField() + + class Meta: + serializer_fields = ['name'] + +``` +Only `name` will be serialized ## License diff --git a/djangoldp/__init__.py b/djangoldp/__init__.py index 790f02aa4e153fc4e9fbf41a833590d4bba23a5e..1396940663cba299c92a2ceecf41a682fab3fecf 100644 --- a/djangoldp/__init__.py +++ b/djangoldp/__init__.py @@ -1,4 +1,5 @@ from django.db.models import options __version__ = '0.0.0' -options.DEFAULT_NAMES += ('rdf_type', 'auto_author') +options.DEFAULT_NAMES += ( +'rdf_type', 'auto_author', 'view_set', 'container_path', 'permission_classes', 'serializer_fields', 'nested_fields') diff --git a/djangoldp/models.py b/djangoldp/models.py index c654e290f376d0e1b72148e326aef754a0acf595..fff174f810d49c335f6a2124bb808072a86250f6 100644 --- a/djangoldp/models.py +++ b/djangoldp/models.py @@ -7,7 +7,7 @@ class Model(models.Model): @classmethod def get_view_set(cls): - view_set = getattr(cls._meta, 'view_set', None) + view_set = getattr(cls._meta, 'view_set', getattr(cls.Meta, 'view_set', None)) if view_set is None: from djangoldp.views import LDPViewSet view_set = LDPViewSet @@ -15,7 +15,7 @@ class Model(models.Model): @classmethod def get_container_path(cls): - path = getattr(cls._meta, 'container_path', None) + path = getattr(cls._meta, 'container_path', getattr(cls.Meta, 'container_path', None)) if path is None: path = "{}s".format(cls._meta.object_name.lower()) diff --git a/djangoldp/tests/models.py b/djangoldp/tests/models.py index a68a803c1f26baa1bdb47ddd2c22706666b4c07f..981e5158b1a2d34472e4e8385994166e1fc080c5 100644 --- a/djangoldp/tests/models.py +++ b/djangoldp/tests/models.py @@ -32,3 +32,22 @@ class Dummy(models.Model): class LDPDummy(Model): some = models.CharField(max_length=255, blank=True, null=True) + +class Invoice(Model): + title = models.CharField(max_length=255, blank=True, null=True) + + +class Batch(Model): + invoice = models.ForeignKey(Invoice, on_delete=models.CASCADE, related_name='batches') + title = models.CharField(max_length=255, blank=True, null=True) + + class Meta: + serializer_fields = ['@id', 'title', 'invoice', 'tasks'] + + +class Task(models.Model): + batch = models.ForeignKey(Batch, on_delete=models.CASCADE, related_name='tasks') + title = models.CharField(max_length=255) + + class Meta: + serializer_fields = ['@id', 'title', 'batch'] diff --git a/djangoldp/urls.py b/djangoldp/urls.py index 3fc889b9564ebe67cb4ff16949ef6f3afaf06344..59efe9c957f2466c8883695dd6ca03d8c8ea37d2 100644 --- a/djangoldp/urls.py +++ b/djangoldp/urls.py @@ -30,6 +30,6 @@ for class_name in model_classes: urls_fct = model_class.get_view_set().urls urlpatterns.append(url(r'^' + path, include( urls_fct(model=model_class, - permission_classes=getattr(model_class._meta, 'permission_classes', []), - fields=getattr(model_class._meta, 'serializer_fields', []), - nested_fields=getattr(model_class._meta, 'nested_fields', []))))) + permission_classes=getattr(model_class._meta, 'permission_classes', getattr(model_class.Meta, 'permission_classes', [])), + fields=getattr(model_class._meta, 'serializer_fields', getattr(model_class.Meta, 'serializer_fields', [])), + nested_fields=getattr(model_class._meta, 'nested_fields', getattr(model_class.Meta, 'nested_fields', []))))))