import json from django.core import serializers from django.core.exceptions import ImproperlyConfigured from django.core.serializers.json import DjangoJSONEncoder from django.http import HttpResponse from django.views.generic import TemplateView from bots.forms import BotForm from bots.models import TelegramBot from cabinet.utils import CabinetViewMixin from config.utils import get_config_form class BaseBotConfigView(CabinetViewMixin, TemplateView): template_name = 'cabinet/bots/bot_form.html' context_object_name = 'feed' def get_queryset(self): return TelegramBot.objects.filter(owner=self.request.user) def get(self, request, *args, **kwargs): self.object = self.get_object() return self.render_to_response(self.get_context_data()) def post(self, request, *args, **kwargs): self.object = self.get_object() bot_form, config_form = self.get_forms() if bot_form.is_valid() and config_form.is_valid(): return self.form_valid(bot_form, config_form) else: context = self.get_context_data( forms=(bot_form, config_form) ) return self.render_to_response(context) def get_forms(self): bot = self.get_object() data = self.request.POST if self.request.method == 'POST' else None files = self.request.FILES if self.request.method == 'POST' else None return BotForm(data=data, files=files, instance=bot, module=self.get_content_type().model_class()), \ get_config_form(self.get_content_type().model_class())(data=data, files=files, instance=bot.config if bot else None) def get_context_data(self, forms=None, **kwargs): ctx = super(BaseBotConfigView, self).get_context_data(**kwargs) ctx['bot_form'], ctx['config_form'] = self.get_forms() if forms is None else forms ctx['bot_module'] = model = self.model if hasattr(model, 'form_context_data'): bot = self.get_object() ctx.update(model.form_context_data(self, bot.config if bot else None)) return ctx @property def model(self): return self.get_content_type().model_class() # django-braces class AjaxResponseMixin(object): """ Mixin allows you to define alternative methods for ajax requests. Similar to the normal get, post, and put methods, you can use get_ajax, post_ajax, and put_ajax. """ def dispatch(self, request, *args, **kwargs): request_method = request.method.lower() if request.accepts("application/json") and request_method in self.http_method_names: handler = getattr(self, "{0}_ajax".format(request_method), self.http_method_not_allowed) self.request = request self.args = args self.kwargs = kwargs return handler(request, *args, **kwargs) return super(AjaxResponseMixin, self).dispatch( request, *args, **kwargs) def get_ajax(self, request, *args, **kwargs): return self.get(request, *args, **kwargs) def post_ajax(self, request, *args, **kwargs): return self.post(request, *args, **kwargs) def put_ajax(self, request, *args, **kwargs): return self.get(request, *args, **kwargs) def delete_ajax(self, request, *args, **kwargs): return self.get(request, *args, **kwargs) class JSONResponseMixin(object): """ A mixin that allows you to easily serialize simple data such as a dict or Django models. """ content_type = None json_dumps_kwargs = None json_encoder_class = DjangoJSONEncoder def get_content_type(self): if self.content_type is not None and not isinstance(self.content_type, str): raise ImproperlyConfigured( '{0} is missing a content type. Define {0}.content_type, ' 'or override {0}.get_content_type().'.format( self.__class__.__name__)) return self.content_type or "application/json" def get_json_dumps_kwargs(self): if self.json_dumps_kwargs is None: self.json_dumps_kwargs = {} self.json_dumps_kwargs.setdefault('ensure_ascii', False) return self.json_dumps_kwargs def render_json_response(self, context_dict, status=200): """ Limited serialization for shipping plain data. Do not use for models or other complex or custom objects. """ json_context = json.dumps( context_dict, cls=self.json_encoder_class, **self.get_json_dumps_kwargs()).encode('utf-8') return HttpResponse(json_context, content_type=self.get_content_type(), status=status) def render_json_object_response(self, objects, **kwargs): """ Serializes objects using Django's builtin JSON serializer. Additional kwargs can be used the same way for django.core.serializers.serialize. """ json_data = serializers.serialize("json", objects, **kwargs) return HttpResponse(json_data, content_type=self.get_content_type())