Last active
February 8, 2020 04:45
-
-
Save edulix/5311365 to your computer and use it in GitHub Desktop.
Generic View for listing, adding and removing items in ManyToManyField for django-rest-framework. Comes with an example =)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE | |
Version 2, December 2004 | |
Copyright (C) 2013 Eduardo Robles Elvira <edulix@wadobo.com> | |
Everyone is permitted to copy and distribute verbatim or modified | |
copies of this license document, and changing it is allowed as long | |
as the name is changed. | |
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE | |
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION | |
0. You just DO WHAT THE FUCK YOU WANT TO. | |
""" | |
from __future__ import unicode_literals | |
from django.views.generic.detail import SingleObjectMixin | |
from django.views.generic.list import MultipleObjectMixin | |
from django.core.exceptions import ImproperlyConfigured | |
from rest_framework import views, mixins, generics, serializers | |
from rest_framework.settings import api_settings | |
from rest_framework.response import Response | |
from rest_framework import status | |
class CRUDManyToManyView(mixins.ListModelMixin, SingleObjectMixin, | |
generics.MultipleObjectAPIView): | |
""" | |
Generic view that provide CRUD behaviour for ManyToMany fields. | |
""" | |
model = None | |
pk_url_kwarg = 'field_pk' | |
field_name = '' | |
model_pk = 'id' | |
queryset = None | |
item = None | |
def get(self, request, *args, **kwargs): | |
return self.list(request, *args, **kwargs) | |
def post(self, request, *args, **kwargs): | |
obj = self.get_object() | |
item = self.get_item() | |
getattr(self.get_item(), self.field_name).add(obj) | |
item = self.get_item().save() | |
return Response(status=status.HTTP_201_CREATED) | |
def delete(self, request, *args, **kwargs): | |
obj = self.get_object() | |
item = self.get_item() | |
getattr(self.get_item(), self.field_name).remove(obj) | |
item = self.get_item().save() | |
return Response(status=status.HTTP_204_NO_CONTENT) | |
def get_item(self): | |
if self.item: | |
return self.item | |
if self.model is None: | |
raise ImproperlyConfigured("%(cls)s is missing a model." % { | |
'cls': self.__class__.__name__ | |
}) | |
item_view = generics.SingleObjectAPIView() | |
item_view.model = self.model | |
item_view.request = self.request | |
item_view.args = self.args | |
item_view.kwargs = self.kwargs | |
self.item = item_view.get_object() | |
return self.item | |
def get_queryset(self): | |
''' | |
Returns the list of items in model_instance.field_name.all() | |
''' | |
if self.queryset: | |
return self.queryset | |
if self.field_name is None: | |
raise ImproperlyConfigured("%(cls)s is missing a field_name." % { | |
'cls': self.__class__.__name__ | |
}) | |
obj = self.get_item() | |
self.queryset = getattr(obj, self.field_name).all() | |
return self.queryset |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from django.db import models | |
class Task(models.Model): | |
name = models.CharField(max_length=140, blank=False, null=False) | |
class Project(models.Model): | |
name = models.CharField(max_length=140, blank=False, null=False) | |
tasks = models.ManyToManyField(Task, related_name='projects') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from rest_framework import serializers | |
from models import Task | |
class TaskSerializer(serializers.ModelSerializer): | |
class Meta: | |
model = Task | |
fields = ('id', 'name') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from django.conf.urls import patterns, url | |
import views | |
urlpatterns = patterns( | |
'', | |
url(r'^projects/(?P<pk>[0-9]+)/tasks/((?P<field_pk>[0-9]+)/)?$', | |
views.ProjectTasks.as_view()), | |
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from models import Project | |
from serializers import TaskSerializer | |
from lib.crudmanytomanyview import CRUDManyToManyView | |
class ProjectTasks(CRUDManyToManyView): | |
model = Project | |
field_name = 'tasks' | |
serializer_class = TaskSerializer |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment