Skip to content

Commit 810549e

Browse files
committed
add a doc on authorization to the Django section
1 parent 87d4556 commit 810549e

File tree

2 files changed

+114
-0
lines changed

2 files changed

+114
-0
lines changed

docs/config.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ ga = "UA-12613282-7"
2121
name = "Django"
2222
pages = [
2323
"/docs/django/tutorial/",
24+
"/docs/django/authorization/",
2425
"/docs/django/filtering/",
2526
]
2627

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
---
2+
title: Authorization
3+
description: Details on how to restrict data access
4+
---
5+
6+
# Authorization in Django
7+
8+
There are two main ways you may want to limit access to data when working
9+
with Graphene and Django: limiting which fields are accessible via GraphQL
10+
and limiting which objects a user can access.
11+
12+
Let's use a simple example model.
13+
14+
```python
15+
from django.db import models
16+
17+
class Post(models.Model):
18+
name = models.CharField(max_length=100)
19+
content = models.TextField()
20+
published = models.BooleanField(default=False)
21+
owner = models.ForeignKey('auth.User')
22+
```
23+
24+
## Limiting Field Access
25+
26+
This is easy, simply use the `only_fields` meta attribute.
27+
28+
```python
29+
from graphene.contrib.django.types import DjangoNode
30+
from .models import Post
31+
32+
class PostNode(DjangoNode):
33+
class Meta:
34+
model = Post
35+
only_fields = ('title', 'content')
36+
```
37+
38+
## Queryset Filtering On Lists
39+
40+
In order to filter which objects are available in a queryset-based list,
41+
define a resolve method for that field and return the desired queryset.
42+
43+
```python
44+
from graphene import ObjectType
45+
from graphene.contrib.django.filter import DjangoFilterConnectionField
46+
from .models import Post
47+
48+
class Query(ObjectType):
49+
all_posts = DjangoFilterConnectionField(CategoryNode)
50+
51+
class Meta:
52+
abstract = True
53+
54+
def resolve_all_posts(self, args, info):
55+
return Post.objects.filter(published=True)
56+
```
57+
58+
## User-based Queryset Filtering
59+
60+
If you are using `graphql-django-view` you can access Django's request object
61+
via `info.request_context`.
62+
63+
```python
64+
from graphene import ObjectType
65+
from graphene.contrib.django.filter import DjangoFilterConnectionField
66+
from .models import Post
67+
68+
class Query(ObjectType):
69+
my_posts = DjangoFilterConnectionField(CategoryNode)
70+
71+
class Meta:
72+
abstract = True
73+
74+
def resolve_my_posts(self, args, info):
75+
if not info.request_context.user.is_authenticated():
76+
return []
77+
else:
78+
return Post.objects.filter(owner=info.request_context.user)
79+
```
80+
81+
If you're using your own view, passing the request context into the schema is
82+
simple.
83+
84+
```python
85+
result = schema.execute(query, request_context=request)
86+
```
87+
88+
## Filtering ID-based node access
89+
90+
In order to add authorization to id-based node access, we need to add a method
91+
to your `DjangoNode`.
92+
93+
```python
94+
from graphene.contrib.django.types import DjangoNode
95+
from .models import Post
96+
97+
class PostNode(DjangoNode):
98+
class Meta:
99+
model = Post
100+
only_fields = ('title', 'content')
101+
102+
@classmethod
103+
def get_node(Cls, id, info):
104+
try:
105+
post = Cls._meta.model.objects.get(id=id)
106+
except Cls._meta.model.DoesNotExist:
107+
return None
108+
109+
if post.published or info.request_context.user is post.owner:
110+
return Cls(instance)
111+
else:
112+
return None
113+
```

0 commit comments

Comments
 (0)