from collections import OrderedDict from django.contrib import auth from django.contrib.auth.middleware import AuthenticationMiddleware from django.db.models import ForeignKey from django.core import serializers from django.http import JsonResponse from pydoc import locate import base64 import json def model_to_dict(model): serialized_obj = serializers.serialize('python', [model]) serialized_obj = serialized_obj[0] serialized_obj = dict(serialized_obj) for key, value in serialized_obj.items(): if isinstance(value, OrderedDict): serialized_obj[key] = dict(value) serialized_obj = serialized_obj['fields'] serialized_obj['id'] = model.id serialized_obj['pk'] = model.pk return serialized_obj class AutologinAuthenticationMiddleware(AuthenticationMiddleware): def process_request(self, request): if 'autologin' not in request.COOKIES: return if request.COOKIES['autologin'] == '': auth.logout(request) return autologin_cookie_value = base64.b64decode(request.COOKIES['autologin']) # Py3 uses a bytes string here, so we need to decode to utf-8 autologin_cookie_value = autologin_cookie_value.decode('utf-8') username = autologin_cookie_value.split(':')[0] password = autologin_cookie_value.split(':')[1] user = auth.authenticate(username=username, password=password) if user is not None: if user.is_active: auth.login(request, user) class FactoryBoyMiddleware(): def _get_foreign_key_fields(self, FactoryBoyClass): foreign_key_fields = [] for field in FactoryBoyClass._meta.model._meta.fields: if isinstance(field, ForeignKey): foreign_key_fields.append(field) return foreign_key_fields def _foreign_key_to_model(self, FactoryBoyClass, factory_boy_args): if not hasattr(FactoryBoyClass, '_meta'): return if not hasattr(FactoryBoyClass._meta.model, '_meta'): return for field in self._get_foreign_key_fields(FactoryBoyClass): for key, value in factory_boy_args.items(): key_name = '{}__pk'.format(field.name) if key == key_name: RelModel = field.foreign_related_fields[0].model del factory_boy_args[key_name] new_key = key_name.replace('__pk', '') factory_boy_args[new_key] = RelModel.objects.first() def process_request(self, request): model_name = request.GET.get('FACTORY_BOY_MODEL_PATH') if not model_name: return get_args = request.GET.get('FACTORY_BOY_ARGS') try: factory_boy_args = json.loads(get_args) except ValueError: factory_boy_args = {} FactoryBoyClass = locate(model_name) if not FactoryBoyClass: msg = 'Factory Boy class "{}" could not be found' return JsonResponse( { 'error': msg.format(model_name) }, status=400 ) self._foreign_key_to_model(FactoryBoyClass, factory_boy_args) try: obj = FactoryBoyClass(**factory_boy_args) except: # noqa return JsonResponse( { 'error': 'FactoryBoyClass "{}" '.format(model_name) + 'could not be instantiated with args "{}"'.format( factory_boy_args ) }, status=400 ) obj_meta = getattr(obj, '_meta', None) if not obj_meta: return JsonResponse( { 'error': 'The FactoryBoyClass "{}" '.format(model_name) + 'instance does not seem to provide a _meta attribute. ' + 'Please check if the Factory Boy class inherits from ' + 'DjangoModelFactory' }, status=400 ) return JsonResponse(model_to_dict(obj), status=201) class QuerySetMiddleware(): def process_request(self, request): model_name = request.GET.get('MODEL_PATH') if not model_name: return get_args = request.GET.get('QUERY_ARGS') try: query_args = json.loads(get_args) except (ValueError, TypeError): query_args = {} ModelClass = locate(model_name) if not ModelClass: msg = 'Class "{}" could not be found' return JsonResponse( { 'error': msg.format(model_name) }, status=400 ) result = [] limit = None if 'limit' in query_args: limit = query_args['limit'] del query_args['limit'] offset = None if 'offset' in query_args: offset = query_args['offset'] del query_args['offset'] if query_args: try: objects = ModelClass.objects.filter(**query_args) except ModelClass.DoesNotExist: objects = [] else: objects = ModelClass.objects.all() if offset and limit: objects = objects[int(offset):int(limit)] elif not offset and limit: objects = objects[:int(limit)] for obj in objects: serialized_obj = model_to_dict(obj) serialized_obj['pk'] = obj.pk result.append(serialized_obj) return JsonResponse(result, safe=False, status=200)