mirror of
https://github.com/graphql-python/graphene.git
synced 2024-11-29 21:13:58 +03:00
Merge pull request #104 from defrex/master
Add a doc on authorization in Django
This commit is contained in:
commit
ba3f1d7690
|
@ -22,6 +22,7 @@ ga = "UA-12613282-7"
|
|||
name = "Django"
|
||||
pages = [
|
||||
"/docs/django/tutorial/",
|
||||
"/docs/django/authorization/",
|
||||
"/docs/django/filtering/",
|
||||
]
|
||||
|
||||
|
|
113
docs/pages/docs/django/authorization.md
Normal file
113
docs/pages/docs/django/authorization.md
Normal file
|
@ -0,0 +1,113 @@
|
|||
---
|
||||
title: Authorization
|
||||
description: Details on how to restrict data access
|
||||
---
|
||||
|
||||
# Authorization in Django
|
||||
|
||||
There are two main ways you may want to limit access to data when working
|
||||
with Graphene and Django: limiting which fields are accessible via GraphQL
|
||||
and limiting which objects a user can access.
|
||||
|
||||
Let's use a simple example model.
|
||||
|
||||
```python
|
||||
from django.db import models
|
||||
|
||||
class Post(models.Model):
|
||||
name = models.CharField(max_length=100)
|
||||
content = models.TextField()
|
||||
published = models.BooleanField(default=False)
|
||||
owner = models.ForeignKey('auth.User')
|
||||
```
|
||||
|
||||
## Limiting Field Access
|
||||
|
||||
This is easy, simply use the `only_fields` meta attribute.
|
||||
|
||||
```python
|
||||
from graphene.contrib.django.types import DjangoNode
|
||||
from .models import Post
|
||||
|
||||
class PostNode(DjangoNode):
|
||||
class Meta:
|
||||
model = Post
|
||||
only_fields = ('title', 'content')
|
||||
```
|
||||
|
||||
## Queryset Filtering On Lists
|
||||
|
||||
In order to filter which objects are available in a queryset-based list,
|
||||
define a resolve method for that field and return the desired queryset.
|
||||
|
||||
```python
|
||||
from graphene import ObjectType
|
||||
from graphene.contrib.django.filter import DjangoFilterConnectionField
|
||||
from .models import Post
|
||||
|
||||
class Query(ObjectType):
|
||||
all_posts = DjangoFilterConnectionField(CategoryNode)
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
|
||||
def resolve_all_posts(self, args, info):
|
||||
return Post.objects.filter(published=True)
|
||||
```
|
||||
|
||||
## User-based Queryset Filtering
|
||||
|
||||
If you are using `graphql-django-view` you can access Django's request object
|
||||
via `info.request_context`.
|
||||
|
||||
```python
|
||||
from graphene import ObjectType
|
||||
from graphene.contrib.django.filter import DjangoFilterConnectionField
|
||||
from .models import Post
|
||||
|
||||
class Query(ObjectType):
|
||||
my_posts = DjangoFilterConnectionField(CategoryNode)
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
|
||||
def resolve_my_posts(self, args, info):
|
||||
if not info.request_context.user.is_authenticated():
|
||||
return []
|
||||
else:
|
||||
return Post.objects.filter(owner=info.request_context.user)
|
||||
```
|
||||
|
||||
If you're using your own view, passing the request context into the schema is
|
||||
simple.
|
||||
|
||||
```python
|
||||
result = schema.execute(query, request_context=request)
|
||||
```
|
||||
|
||||
## Filtering ID-based node access
|
||||
|
||||
In order to add authorization to id-based node access, we need to add a method
|
||||
to your `DjangoNode`.
|
||||
|
||||
```python
|
||||
from graphene.contrib.django.types import DjangoNode
|
||||
from .models import Post
|
||||
|
||||
class PostNode(DjangoNode):
|
||||
class Meta:
|
||||
model = Post
|
||||
only_fields = ('title', 'content')
|
||||
|
||||
@classmethod
|
||||
def get_node(Cls, id, info):
|
||||
try:
|
||||
post = Cls._meta.model.objects.get(id=id)
|
||||
except Cls._meta.model.DoesNotExist:
|
||||
return None
|
||||
|
||||
if post.published or info.request_context.user is post.owner:
|
||||
return Cls(instance)
|
||||
else:
|
||||
return None
|
||||
```
|
Loading…
Reference in New Issue
Block a user