README.md 6.03 KB
Newer Older
Sylvain Le Bon's avatar
Sylvain Le Bon committed
1 2 3 4 5 6 7 8 9 10 11
## Synopsis

This module is an add-on for Django REST Framework that serves a django model respecting the Linked Data Platform convention.

It aims at enabling people with little development skills to serve their own data, to be used with a LDP application.

## Requirements

* Django (known to work with django 1.11)
* Django Rest Framework
* pyld
12 13
* django-guardian
* djangorestframework-guardian
Sylvain Le Bon's avatar
Sylvain Le Bon committed
14 15 16

## Installation

Benoit Alessandroni's avatar
Benoit Alessandroni committed
17
1. Install this module and all its dependencies
Sylvain Le Bon's avatar
Sylvain Le Bon committed
18 19 20 21 22

```
pip install djangoldp
```

Benoit Alessandroni's avatar
Benoit Alessandroni committed
23
2. Create a django project
Sylvain Le Bon's avatar
Sylvain Le Bon committed
24 25 26 27 28
 
```
django-admin startproject myldpserver
```

Benoit Alessandroni's avatar
Benoit Alessandroni committed
29
3. Create your django model inside a file myldpserver/myldpserver/models.py
30 31
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)
Sylvain Le Bon's avatar
Sylvain Le Bon committed
32 33

```
34
from djangoldp.models import Model
Sylvain Le Bon's avatar
Sylvain Le Bon committed
35

36
class Todo(Model):
Sylvain Le Bon's avatar
Sylvain Le Bon committed
37 38
    name = models.CharField(max_length=255)
    deadline = models.DateTimeField()
39
    
Sylvain Le Bon's avatar
Sylvain Le Bon committed
40 41 42

```

43 44 45 46 47 48 49
3.1. Configure container path (optional)
By default it will be "todos/" with an S for model called Todo

```
<Model>._meta.container_path = "/my-path/"
```

50

51
3.2. Configure field visibility (optional) 
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
Note that at this stage you can limit access to certain fields of models using

```
<Model>._meta.serializer_fields (<>list of field names to show>)
```

 For example, if you have a model with a related field with type **django.contrib.auth.models.User** you don't want to show personal details or password hashes.

E.g.

```
from django.contrib.auth.models import User

User._meta.serializer_fields  = ('username','first_name','last_name')
```

68 69
Note that this will be overridden if you explicitly set the fields= parameter as an argument to LDPViewSet.urls(), and filtered if you set the excludes= parameter.

Benoit Alessandroni's avatar
Benoit Alessandroni committed
70
4. Add a url in your urls.py:
Alexandre's avatar
Alexandre committed
71

Sylvain Le Bon's avatar
Sylvain Le Bon committed
72
```
Sylvain Le Bon's avatar
Sylvain Le Bon committed
73 74
from django.conf.urls import url
from django.contrib import admin
Sylvain Le Bon's avatar
Sylvain Le Bon committed
75
from djangoldp.views import LDPViewSet
Sylvain Le Bon's avatar
Sylvain Le Bon committed
76
from .models import Todo
Sylvain Le Bon's avatar
Sylvain Le Bon committed
77 78

urlpatterns = [
79 80
    url(r'^', include('djangoldp.urls')),
    url(r'^admin/', admin.site.urls), # Optional
Sylvain Le Bon's avatar
Sylvain Le Bon committed
81 82
]
```
Alexandre's avatar
Alexandre committed
83

84 85 86 87 88 89 90
This creates 2 routes for each Model, one for the list, and one with an ID listing the detail of an object.

You could also only use this line in settings.py instead:

```
ROOT_URLCONF = 'djangoldp.urls'
```
Sylvain Le Bon's avatar
Sylvain Le Bon committed
91

Benoit Alessandroni's avatar
Benoit Alessandroni committed
92
5. In the settings.py file, add your application name at the beginning of the application list, and add the following lines
Sylvain Le Bon's avatar
Sylvain Le Bon committed
93 94 95 96 97 98

```
STATIC_ROOT = os.path.join(os.path.dirname(BASE_DIR), 'static')
LDP_RDF_CONTEXT = 'https://cdn.happy-dev.fr/owl/hdcontext.jsonld'
```

Benoit Alessandroni's avatar
Benoit Alessandroni committed
99
6. You can also register your model for the django administration site
Sylvain Le Bon's avatar
Sylvain Le Bon committed
100 101 102 103 104 105 106 107

```
from django.contrib import admin
from .models import Todo

admin.site.register(Todo)
```

Benoit Alessandroni's avatar
Benoit Alessandroni committed
108
7. You then need to have your WSGI server pointing on myldpserver/myldpserver/wsgi.py
Sylvain Le Bon's avatar
Sylvain Le Bon committed
109

Benoit Alessandroni's avatar
Benoit Alessandroni committed
110
8. You will probably need to create a super user
Alexandre's avatar
Alexandre committed
111 112 113 114
```
./manage.py createsuperuser
```

Benoit Alessandroni's avatar
Benoit Alessandroni committed
115
9. If you have no CSS on the admin screens : 
Alexandre's avatar
Alexandre committed
116 117 118 119
```
./manage.py collectstatic
```

Alexandre's avatar
Alexandre committed
120 121 122 123 124 125
## Execution
To start the server, `cd` to the root of your Django project and run :
```
python3 manage.py runserver
```

Sylvain Le Bon's avatar
Sylvain Le Bon committed
126
## Custom Parameters to LDPViewSet
Sylvain Le Bon's avatar
Sylvain Le Bon committed
127

Sylvain Le Bon's avatar
Sylvain Le Bon committed
128 129 130 131 132 133 134 135 136 137 138
### lookup_field
Can be used to use a slug in the url instead of the primary key.
```
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>/` 
```
139
   <Model>._meta.nested_fields=["skills"]
Sylvain Le Bon's avatar
Sylvain Le Bon committed
140 141
```

Benoit Alessandroni's avatar
Benoit Alessandroni committed
142

143 144 145 146
## Custom Meta options on models

### rdf_type
### auto_author
Alexandre's avatar
Alexandre committed
147 148
This property allows to associate a model with the logged in user.

149

Alexandre's avatar
Alexandre committed
150
```python
Alexandre's avatar
Alexandre committed
151 152 153 154
class MyModel(models.Model):
    author_user = models.ForeignKey(settings.AUTH_USER_MODEL)
    class Meta:
        auto_author = 'author_user'
Alexandre's avatar
Alexandre committed
155
```
Alexandre's avatar
Alexandre committed
156 157
Now when an instance of `MyModel` is saved, its `author_user` property will be set to the current user. 

158
## permissions_classes
159 160
This allows you to add permissions for anonymous, logged in user, author ... in the url:
By default `LDPPermissions` is used.
161 162
Specific permissin classes can be developed to fit special needs.

163
## anonymous_perms, user_perms, owner_perms
164 165

Those allow you to set permissions from your model's meta.
166

167 168 169 170 171 172 173 174 175 176 177
You can give the following permission to them:
* `view`
* `add`
* `change`
* `control`
* `delete`
* `inherit`

With inherit, Users can herit from Anons. Also Owners can herit from Users.

Eg. with this model Anons can view, Auths can add & Owners can edit & delete.
178

179 180 181 182 183 184 185 186
```python
from djangoldp.models import Model

class Todo(Model):
    name = models.CharField(max_length=255)
    deadline = models.DateTimeField()
    
    class Meta:
187 188 189
        anonymous_perms = ['view']
        authenticated_perms = ['inherit', 'add']
        owner_perms = ['inherit', 'change', 'control', 'delete']
190 191 192 193 194 195
```


Important note:
If you need to give permissions to owner's object, don't forget to add auto_author in model's meta

196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226
### 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
227

228 229 230
## 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

231 232 233 234 235 236 237 238 239 240
## Pagination
To enable pagination feature just add this configuration to the server `settings.py` :

```
REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
    'PAGE_SIZE': 20
}
```
 
Sylvain Le Bon's avatar
Sylvain Le Bon committed
241 242 243
## License

Licence MIT