2017-08-24 12:26:55 +02:00
|
|
|
from typing import Any, Dict, List # noqa
|
2017-08-23 20:51:06 +02:00
|
|
|
|
2017-09-26 14:19:48 +02:00
|
|
|
from django.contrib.staticfiles import finders
|
|
|
|
from django.core.exceptions import ImproperlyConfigured
|
|
|
|
from django.http import HttpResponse
|
2015-02-17 20:07:44 +01:00
|
|
|
from django.views.decorators.csrf import ensure_csrf_cookie
|
2017-08-24 12:26:55 +02:00
|
|
|
from django.views.generic.base import View
|
2015-02-12 22:42:54 +01:00
|
|
|
from rest_framework.response import Response
|
2015-02-17 20:07:44 +01:00
|
|
|
from rest_framework.views import APIView as _APIView
|
2012-02-20 17:46:45 +01:00
|
|
|
|
2012-04-13 11:35:53 +02:00
|
|
|
|
2015-02-17 20:07:44 +01:00
|
|
|
class CSRFMixin:
|
|
|
|
"""
|
|
|
|
Adds the csrf cookie to the response.
|
|
|
|
"""
|
|
|
|
|
|
|
|
@classmethod
|
2017-08-24 12:26:55 +02:00
|
|
|
def as_view(cls, *args: Any, **kwargs: Any) -> View:
|
|
|
|
view = super().as_view(*args, **kwargs) # type: ignore
|
2015-02-17 20:07:44 +01:00
|
|
|
return ensure_csrf_cookie(view)
|
|
|
|
|
|
|
|
|
2015-02-12 22:42:54 +01:00
|
|
|
class APIView(_APIView):
|
|
|
|
"""
|
|
|
|
The Django Rest framework APIView with improvements for OpenSlides.
|
|
|
|
"""
|
|
|
|
|
2017-08-23 20:51:06 +02:00
|
|
|
http_method_names = [] # type: List[str]
|
2015-02-12 22:42:54 +01:00
|
|
|
"""
|
|
|
|
The allowed actions have to be explicitly defined.
|
|
|
|
|
|
|
|
Django allowes the following:
|
|
|
|
http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
|
|
|
|
"""
|
|
|
|
|
2017-08-24 12:26:55 +02:00
|
|
|
def get_context_data(self, **context: Any) -> Dict[str, Any]:
|
2015-02-12 22:42:54 +01:00
|
|
|
"""
|
|
|
|
Returns the context for the response.
|
|
|
|
"""
|
|
|
|
return context
|
|
|
|
|
2017-08-24 12:26:55 +02:00
|
|
|
def method_call(self, request: Any, *args: Any, **kwargs: Any) -> Any:
|
2015-02-12 22:42:54 +01:00
|
|
|
"""
|
|
|
|
Http method that returns the response object with the context data.
|
|
|
|
"""
|
|
|
|
return Response(self.get_context_data())
|
|
|
|
|
|
|
|
# Add the http-methods and delete the method "method_call"
|
|
|
|
get = post = put = patch = delete = head = options = trace = method_call
|
|
|
|
del method_call
|
2017-09-26 14:19:48 +02:00
|
|
|
|
|
|
|
|
2017-09-28 09:35:05 +02:00
|
|
|
class TemplateView(View):
|
2017-09-26 14:19:48 +02:00
|
|
|
"""
|
2017-09-28 09:35:05 +02:00
|
|
|
A view to serve a single cached template file. Subclasses have to provide 'template_name'.
|
2018-01-16 16:02:23 +01:00
|
|
|
The state dict is used to cache the template. The state variable is static, but the object ID
|
|
|
|
is not allowed to change. So the State has to be saved in this dict. Search for 'Borg design
|
|
|
|
pattern' for more information.
|
2017-09-26 14:19:48 +02:00
|
|
|
"""
|
|
|
|
template_name = None # type: str
|
2018-01-16 16:02:23 +01:00
|
|
|
state = {} # type: Dict[str, str]
|
2017-09-26 14:19:48 +02:00
|
|
|
|
|
|
|
def __init__(self, *args: Any, **kwargs: Any) -> None:
|
|
|
|
super().__init__(*args, **kwargs)
|
|
|
|
|
|
|
|
if self.template_name is None:
|
2018-01-23 08:49:13 +01:00
|
|
|
raise ImproperlyConfigured("'template_name' is not provided.")
|
2017-09-26 14:19:48 +02:00
|
|
|
|
2018-01-23 08:49:13 +01:00
|
|
|
if self.template_name not in self.state:
|
2018-01-16 16:02:23 +01:00
|
|
|
with open(finders.find(self.template_name)) as template:
|
2018-01-23 08:49:13 +01:00
|
|
|
self.state[self.template_name] = template.read()
|
2017-09-26 14:19:48 +02:00
|
|
|
|
|
|
|
def get(self, *args: Any, **kwargs: Any) -> HttpResponse:
|
2018-01-23 08:49:13 +01:00
|
|
|
return HttpResponse(self.state[self.template_name])
|