diff --git a/README.md b/README.md index 59e28d42547d4a28629bebcc57216c88360daa10..cbba9f6f7032cc146a5f0e2169d501276572ea29 100644 --- a/README.md +++ b/README.md @@ -16,42 +16,39 @@ It aims at enabling people with little development skills to serve their own dat 1. Install this module and all its dependencies -``` -pip install djangoldp +```bash +$ pip install djangoldp ``` 2. Create a django project -``` -django-admin startproject myldpserver +```bash +$ django-admin startproject myldpserver ``` 3. Create your django model inside a file myldpserver/myldpserver/models.py Note that container_path will be use to resolve instance iri and container iri In the future it could also be used to auto configure django router (e.g. urls.py) -``` +```python from djangoldp.models import Model class Todo(Model): name = models.CharField(max_length=255) deadline = models.DateTimeField() - - ``` 3.1. Configure container path (optional) By default it will be "todos/" with an S for model called Todo -``` +```python <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 -``` +```python <Model>._meta.serializer_fields (<>list of field names to show>) ``` @@ -59,7 +56,7 @@ Note that at this stage you can limit access to certain fields of models using E.g. -``` +```python from django.contrib.auth.models import User User._meta.serializer_fields = ('username','first_name','last_name') @@ -69,7 +66,7 @@ Note that this will be overridden if you explicitly set the fields= parameter as 4. Add a url in your urls.py: -``` +```python from django.conf.urls import url from django.contrib import admin from djangoldp.views import LDPViewSet @@ -85,20 +82,20 @@ This creates 2 routes for each Model, one for the list, and one with an ID listi You could also only use this line in settings.py instead: -``` +```python ROOT_URLCONF = 'djangoldp.urls' ``` 5. In the settings.py file, add your application name at the beginning of the application list, and add the following lines -``` +```python STATIC_ROOT = os.path.join(os.path.dirname(BASE_DIR), 'static') LDP_RDF_CONTEXT = 'https://cdn.happy-dev.fr/owl/hdcontext.jsonld' ``` 6. You can also register your model for the django administration site -``` +```python from django.contrib import admin from .models import Todo @@ -108,42 +105,51 @@ admin.site.register(Todo) 7. You then need to have your WSGI server pointing on myldpserver/myldpserver/wsgi.py 8. You will probably need to create a super user -``` -./manage.py createsuperuser -``` -9. If you have no CSS on the admin screens : +```bash +$ ./manage.py createsuperuser ``` -./manage.py collectstatic + +9. If you have no CSS on the admin screens : + +```bash +$ ./manage.py collectstatic ``` ## Execution + To start the server, `cd` to the root of your Django project and run : -``` -python3 manage.py runserver + +```bash +$ python3 manage.py runserver ``` ## Custom Parameters to LDPViewSet ### lookup_field + Can be used to use a slug in the url instead of the primary key. -``` + +```python LDPViewSet.urls(model=User, lookup_field='username') ``` ### nested_fields + list of ForeignKey, ManyToManyField, OneToOneField and their reverse relations. When a field is listed in this parameter, a container will be created inside each single element of the container. -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>/` -``` - <Model>._meta.nested_fields=["skills"] -``` +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>/` +```python +<Model>._meta.nested_fields=["skills"] +``` ## Custom Meta options on models ### rdf_type + ### auto_author + This property allows to associate a model with the logged in user. @@ -153,9 +159,11 @@ class MyModel(models.Model): class Meta: auto_author = 'author_user' ``` + Now when an instance of `MyModel` is saved, its `author_user` property will be set to the current user. ## permissions_classes + This allows you to add permissions for anonymous, logged in user, author ... in the url: By default `LDPPermissions` is used. Specific permissin classes can be developed to fit special needs. @@ -165,6 +173,7 @@ Specific permissin classes can be developed to fit special needs. Those allow you to set permissions from your model's meta. You can give the following permission to them: + * `view` * `add` * `change` @@ -197,10 +206,11 @@ class Todo(Model): 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 +### view_set + In case of custom viewset, you can use -``` +```python from djangoldp.models import Model class Todo(Model): @@ -212,37 +222,43 @@ class Todo(Model): ``` -### container_path +### container_path + See 3.1. Configure container path (optional) -### serializer_fields -``` +### serializer_fields + +```python 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 ## Custom urls + To add customs urls who can not be add through the `Model` class, it's possible de create a file named `djangoldp_urls.py`. It will be executed like an `urls.py` file ## Pagination + To enable pagination feature just add this configuration to the server `settings.py` : -``` +```python REST_FRAMEWORK = { 'DEFAULT_PAGINATION_CLASS': 'djangoldp.pagination.LDPPagination', 'PAGE_SIZE': 20 } ``` - + ## Sources + To enable sources auto creation for all models, change `djangoldp` by `djangoldp.apps.DjangoldpConfig`, on `INSTALLED_APPS` ```python @@ -251,6 +267,17 @@ INSTALLED_APPS = [ ] ``` +## 302 on domain mismatch + +To enable 302 redirection on domain mismatch, add `djangoldp.middleware.AllowOnlySiteUrl` on `MIDDLEWARE` + +This ensure that your clients will use `SITE_URL` and avoid mismatch betwen url & the id of a resource/container + +```python +MIDDLEWARE = [ + 'djangoldp.middleware.AllowOnlySiteUrl', +] +``` ## License diff --git a/djangoldp/middleware.py b/djangoldp/middleware.py new file mode 100644 index 0000000000000000000000000000000000000000..2e14269091e2f44ae5373f8631cd6341ee273528 --- /dev/null +++ b/djangoldp/middleware.py @@ -0,0 +1,15 @@ +from django.conf import settings +from django.utils.http import is_safe_url +from django.shortcuts import redirect + + +class AllowOnlySiteUrl: + def __init__(self, get_response): + self.get_response = get_response + + def __call__(self, request): + if(is_safe_url(request.get_raw_uri(), allowed_hosts=settings.SITE_URL)): + response = self.get_response(request) + return response + else: + return redirect('{}{}'.format(settings.SITE_URL, request.path))