diff --git a/__init__.py b/__init__.py index 13b1ce9e4883533ac09a2a773752cbd8dbc04046..ed2171212bcb88a02d02fa1822197a68c7a13df9 100644 --- a/__init__.py +++ b/__init__.py @@ -1,3 +1,3 @@ from django.db.models import options -options.DEFAULT_NAMES += ('rdf_type',) +options.DEFAULT_NAMES += ('rdf_type', 'auto_author') diff --git a/views.py b/views.py index 44388a952ac9c9d9a1b9446bcfaef7b768fdfd8e..f70d107b3926bdf06fc2bc9b75d649d9ce533772 100644 --- a/views.py +++ b/views.py @@ -26,59 +26,10 @@ class NoCSRFAuthentication(SessionAuthentication): def enforce_csrf(self, request): return - -class LDPViewSet(ModelViewSet): - model = None - fields = None - exclude = None - parent_model = None - nested_field = None - nested_related_name = None - list_actions = {'get': 'list', 'post': 'create'} - detail_actions = {'get': 'retrieve', 'put': 'update', 'patch': 'partial_update', 'delete': 'destroy'} - renderer_classes = (JSONLDRenderer, ) - parser_classes = (JSONLDParser, ) - authentication_classes = (NoCSRFAuthentication,) - - def __init__(self, **kwargs): - super().__init__(**kwargs) - model_name = self.model._meta.object_name.lower() - lookup_field = get_resolver().reverse_dict[model_name+'-detail'][0][0][1][0] - meta_args = {'model': self.model, 'extra_kwargs': {'@id': {'lookup_field': lookup_field}}} - if self.fields: - meta_args['fields'] = self.fields - else: - meta_args['exclude'] = self.exclude or () - meta_class = type('Meta', (), meta_args) - self.serializer_class = type(LDPSerializer)(model_name+'Serializer', (LDPSerializer,), {'Meta': meta_class}) - - def get_parent(self): - return self.parent_model.objects.get(id=self.kwargs[self.lookup_field]) - - def perform_create(self, serializer): - if self.parent_model: - serializer.validated_data[self.nested_related_name] = self.get_parent() - return super().perform_create(serializer) - - def get_queryset(self, *args, **kwargs): - if self.parent_model: - return getattr(self.get_parent(), self.nested_field).all() - if self.model: - return self.model.objects.all() - else: - return super(LDPView, self).get_queryset(*args, **kwargs) - - def dispatch(self, request, *args, **kwargs): - response = super(LDPViewSet, self).dispatch(request, *args, **kwargs) - response["Access-Control-Allow-Origin"] = request.META.get('HTTP_ORIGIN') - response["Access-Control-Allow-Methods"] = "POST,PUT" - response["Access-Control-Allow-Headers"] = "Content-Type, if-match" - response["Access-Control-Allow-Credentials"] = 'true' - response["Accept-Post"] = "application/ld+json" - return response - +class LDPViewSetGenerator(ModelViewSet): @classonlymethod def get_model(cls, **kwargs): + '''gets the model in the arguments or in the viewset definition''' model = kwargs.get('model') or cls.model if isinstance(model, str): model = apps.get_model(model) @@ -86,6 +37,7 @@ class LDPViewSet(ModelViewSet): @classonlymethod def get_detail_url(cls, lookup_field=None, base_url='', **kwargs): + '''builds the detail url based on the lookup_field''' lookup_field = lookup_field or kwargs.get('lookup_field') or cls.lookup_field if lookup_field and lookup_field != 'pk': return r'{}(?P<{}>[\w-]+)/'.format(base_url, lookup_field) @@ -126,3 +78,56 @@ class LDPViewSet(ModelViewSet): url(r'^$', cls.as_view(cls.list_actions, **kwargs), name='{}-list'.format(model_name)), url(detail_url+'$', cls.as_view(cls.detail_actions, **kwargs), name='{}-detail'.format(model_name)), ] + cls.get_nested_urls(detail_url, model_name, **kwargs)) + +class LDPViewSet(LDPViewSetGenerator): + model = None + fields = None + exclude = None + parent_model = None + nested_field = None + nested_related_name = None + list_actions = {'get': 'list', 'post': 'create'} + detail_actions = {'get': 'retrieve', 'put': 'update', 'patch': 'partial_update', 'delete': 'destroy'} + renderer_classes = (JSONLDRenderer, ) + parser_classes = (JSONLDParser, ) + authentication_classes = (NoCSRFAuthentication,) + + def __init__(self, **kwargs): + super().__init__(**kwargs) + model_name = self.model._meta.object_name.lower() + lookup_field = get_resolver().reverse_dict[model_name+'-detail'][0][0][1][0] + meta_args = {'model': self.model, 'extra_kwargs': {'@id': {'lookup_field': lookup_field}}} + if self.fields: + meta_args['fields'] = self.fields + else: + meta_args['exclude'] = self.exclude or () + meta_class = type('Meta', (), meta_args) + self.serializer_class = type(LDPSerializer)(model_name+'Serializer', (LDPSerializer,), {'Meta': meta_class}) + + def get_parent(self): + return self.parent_model.objects.get(id=self.kwargs[self.lookup_field]) + + def perform_create(self, serializer): + create_args = {} + if self.parent_model: + create_args[self.nested_related_name] = self.get_parent() + if hasattr(self.model._meta, 'auto_author'): + create_args[self.model._meta.auto_author] = self.request.user + serializer.save(**create_args) + + def get_queryset(self, *args, **kwargs): + if self.parent_model: + return getattr(self.get_parent(), self.nested_field).all() + if self.model: + return self.model.objects.all() + else: + return super(LDPView, self).get_queryset(*args, **kwargs) + + def dispatch(self, request, *args, **kwargs): + response = super(LDPViewSet, self).dispatch(request, *args, **kwargs) + response["Access-Control-Allow-Origin"] = request.META.get('HTTP_ORIGIN') + response["Access-Control-Allow-Methods"] = "POST,PUT" + response["Access-Control-Allow-Headers"] = "Content-Type, if-match" + response["Access-Control-Allow-Credentials"] = 'true' + response["Accept-Post"] = "application/ld+json" + return response