Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Factory:Rebuild
python-django-braces
modernize-braces.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File modernize-braces.patch of Package python-django-braces
From 0031b635b03a4d25c240a9619e4ba5e6433c2697 Mon Sep 17 00:00:00 2001 From: Kenneth Love <klove@oreilly.com> Date: Mon, 8 Nov 2021 16:29:37 -0800 Subject: [PATCH 01/11] New description --- braces/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) Index: django-braces-1.15.0/braces/__init__.py =================================================================== --- django-braces-1.15.0.orig/braces/__init__.py +++ django-braces-1.15.0/braces/__init__.py @@ -2,7 +2,7 @@ django-braces mixins library ---------------------------- -Several mixins for making Django's generic class-based views more useful. +Mixins to make Django's generic class-based views simpler. :copyright: (c) 2013 by Kenneth Love and Chris Jones :license: BSD 3-clause. See LICENSE for more details Index: django-braces-1.15.0/braces/forms.py =================================================================== --- django-braces-1.15.0.orig/braces/forms.py +++ django-braces-1.15.0/braces/forms.py @@ -1,4 +1,4 @@ -class UserKwargModelFormMixin(object): +class UserKwargModelFormMixin: """ Generic model form mixin for popping user out of the kwargs and attaching it to the instance. @@ -9,6 +9,6 @@ class UserKwargModelFormMixin(object): """ def __init__(self, *args, **kwargs): - self.user = kwargs.pop("user", None) # Pop the user off the - # passed in kwargs. + """Remove the user from **kwargs and assign it on the object""" + self.user = kwargs.pop("user", None) super(UserKwargModelFormMixin, self).__init__(*args, **kwargs) Index: django-braces-1.15.0/braces/views/_access.py =================================================================== --- django-braces-1.15.0.orig/braces/views/_access.py +++ django-braces-1.15.0/braces/views/_access.py @@ -1,6 +1,6 @@ import inspect import datetime -import re +import urllib.parse from django.conf import settings from django.contrib.auth import REDIRECT_FIELD_NAME @@ -18,10 +18,9 @@ from django.utils.encoding import force_ from django.utils.timezone import now -class AccessMixin(object): +class AccessMixin: """ - 'Abstract' mixin that gives access mixins the same customizable - functionality. + Base access mixin. All other access mixins should extend this one. """ login_url = None @@ -29,6 +28,10 @@ class AccessMixin(object): redirect_field_name = REDIRECT_FIELD_NAME # Set by django.contrib.auth redirect_unauthenticated_users = False + def __init__(self, *args, **kwargs): + self._class_name = self.__class__.__name__ + super().__init__(*args, **kwargs) + def get_login_url(self): """ Override this method to customize the login_url. @@ -36,8 +39,8 @@ class AccessMixin(object): login_url = self.login_url or settings.LOGIN_URL if not login_url: raise ImproperlyConfigured( - "Define {0}.login_url or settings.LOGIN_URL or override " - "{0}.get_login_url().".format(self.__class__.__name__) + f"Define {self._class_name}.login_url or settings.LOGIN_URL or " + f"override {self._class_name}.get_login_url()." ) return force_str(login_url) @@ -48,11 +51,9 @@ class AccessMixin(object): """ if self.redirect_field_name is None: raise ImproperlyConfigured( - "{0} is missing the " - "redirect_field_name. Define {0}.redirect_field_name or " - "override {0}.get_redirect_field_name().".format( - self.__class__.__name__ - ) + f"{self._class_name} is missing the redirect_field_name. " + f"Define {self._class_name}.redirect_field_name or " + f"override {self._class_name}.get_redirect_field_name()." ) return self.redirect_field_name @@ -92,7 +93,7 @@ class AccessMixin(object): class LoginRequiredMixin(AccessMixin): """ - View mixin which verifies that the user is authenticated. + Requires the user to be authenticated. NOTE: This should be the left-most mixin of a view, except when @@ -104,21 +105,17 @@ class LoginRequiredMixin(AccessMixin): if not request.user.is_authenticated: return self.handle_no_permission(request) - return super(LoginRequiredMixin, self).dispatch( - request, *args, **kwargs - ) + return super().dispatch(request, *args, **kwargs) -class AnonymousRequiredMixin(object): +class AnonymousRequiredMixin(AccessMixin): """ - View mixin which redirects to a specified URL if authenticated. - Can be useful if you wanted to prevent authenticated users from - accessing signup pages etc. + Requires the user to be unauthenticated. NOTE: This should be the left-most mixin of a view. - Example Usage + ## Example Usage class SomeView(AnonymousRequiredMixin, ListView): ... @@ -132,36 +129,31 @@ class AnonymousRequiredMixin(object): def dispatch(self, request, *args, **kwargs): if request.user.is_authenticated: return HttpResponseRedirect(self.get_authenticated_redirect_url()) - return super(AnonymousRequiredMixin, self).dispatch( - request, *args, **kwargs - ) + return super().dispatch(request, *args, **kwargs) def get_authenticated_redirect_url(self): """Return the reversed authenticated redirect url.""" if not self.authenticated_redirect_url: raise ImproperlyConfigured( - "{0} is missing an authenticated_redirect_url " - "url to redirect to. Define " - "{0}.authenticated_redirect_url or override " - "{0}.get_authenticated_redirect_url().".format( - self.__class__.__name__ - ) + f"{self._class_name} is missing an authenticated_redirect_url " + f"url to redirect to. Define {self._class_name}.authenticated_redirect_url " + f"or override {self._class_name}.get_authenticated_redirect_url()." ) return resolve_url(self.authenticated_redirect_url) class PermissionRequiredMixin(AccessMixin): """ - View mixin which verifies that the logged in user has the specified - permission. + The request users must have certain permission(s) + + ## Attributes - Class Settings `permission_required` - the permission to check for. `login_url` - the login url of site `redirect_field_name` - defaults to "next" `raise_exception` - defaults to False - raise 403 if set to True - Example Usage + ## Example Usage class SomeView(PermissionRequiredMixin, ListView): ... @@ -175,7 +167,7 @@ class PermissionRequiredMixin(AccessMixi ... """ - permission_required = None # Default required perms to none + permission_required = None # No permissions are required by default object_level_permissions = False def get_permission_required(self, request=None): @@ -188,8 +180,8 @@ class PermissionRequiredMixin(AccessMixi # view, or raise a configuration error. if self.permission_required is None: raise ImproperlyConfigured( - '{0} requires the "permission_required" attribute to be ' - "set.".format(self.__class__.__name__) + f'{self._class_name} requires the "permission_required" ' + "attribute to be set." ) return self.permission_required @@ -226,9 +218,7 @@ class PermissionRequiredMixin(AccessMixi if not has_permission: return self.handle_no_permission(request) - return super(PermissionRequiredMixin, self).dispatch( - request, *args, **kwargs - ) + return super().dispatch(request, *args, **kwargs) class MultiplePermissionsRequiredMixin(PermissionRequiredMixin): @@ -242,14 +232,14 @@ class MultiplePermissionsRequiredMixin(P permissions in a different format, they should still work. By specifying the `all` key, the user must have all of - the permissions in the passed in list. + the permissions in the list. - By specifying The `any` key , the user must have ONE of the set + By specifying the `any` key , the user must have at least one of the permissions in the list. Class Settings `permissions` - This is required to be a dict with one or both - keys of `all` and/or `any` containing a list or tuple of + keys of `all` and `any` containing a list or tuple of permissions. `login_url` - the login url of site `redirect_field_name` - defaults to "next" @@ -278,29 +268,25 @@ class MultiplePermissionsRequiredMixin(P def check_permissions(self, request): permissions = self.get_permission_required(request) - perms_all = permissions.get("all") or None - perms_any = permissions.get("any") or None + perms_all = permissions.get("all") + perms_any = permissions.get("any") self._check_permissions_keys_set(perms_all, perms_any) self._check_perms_keys("all", perms_all) self._check_perms_keys("any", perms_any) - # If perms_all, check that user has all permissions in the list/tuple + # Check that user has all permissions in the list/tuple if perms_all: + # Why not `return request.user.has_perms(perms_all)`? + # There may be optional permissions below. if not request.user.has_perms(perms_all): return False # If perms_any, check that user has at least one in the list/tuple if perms_any: - has_one_perm = False - for perm in perms_any: - if request.user.has_perm(perm): - has_one_perm = True - break - - if not has_one_perm: + any_perms = [request.user.has_perm(perm) for perm in perms_any] + if not any_perms or not any(any_perms): return False - return True def _check_permissions_attr(self): @@ -309,8 +295,8 @@ class MultiplePermissionsRequiredMixin(P """ if self.permissions is None or not isinstance(self.permissions, dict): raise ImproperlyConfigured( - '{0} requires the "permissions" attribute to be set as a ' - "dict.".format(self.__class__.__name__) + f'{self._class_name} requires the `permissions` attribute' + "to be set as a dict." ) def _check_permissions_keys_set(self, perms_all=None, perms_any=None): @@ -321,10 +307,8 @@ class MultiplePermissionsRequiredMixin(P """ if perms_all is None and perms_any is None: raise ImproperlyConfigured( - '{0} requires the "permissions" attribute to be set to a ' - 'dict and the "any" or "all" key to be set.'.format( - self.__class__.__name__ - ) + f'{self._class_name} requires the `permissions` attribute to ' + f"be set to a dict and the `any` or `all` key to be set." ) def _check_perms_keys(self, key=None, perms=None): @@ -334,8 +318,8 @@ class MultiplePermissionsRequiredMixin(P """ if perms and not isinstance(perms, (list, tuple)): raise ImproperlyConfigured( - "{0} requires the permisions dict {1} value to be a " - "list or tuple.".format(self.__class__.__name__, key) + f"{self._class_name} requires the permissions dict {key} value " + "to be a list or tuple." ) @@ -343,23 +327,25 @@ class GroupRequiredMixin(AccessMixin): group_required = None def get_group_required(self): - if self.group_required is None or ( + if any([ + self.group_required is None, not isinstance(self.group_required, (list, tuple, str)) - ): + ]): raise ImproperlyConfigured( - '{0} requires the "group_required" attribute to be set and be ' - "one of the following types: string, unicode, list or " - "tuple".format(self.__class__.__name__) + f'{self._class_name} requires the `group_required` attribute ' + "to be set and be a string, list, or tuple." ) if not isinstance(self.group_required, (list, tuple)): self.group_required = (self.group_required,) return self.group_required def check_membership(self, groups): - """Check required group(s)""" + """Check for user's membership in required groups. Superusers are + automatically members""" if self.request.user.is_superuser: return True + user_groups = self.request.user.groups.values_list("name", flat=True) return set(groups).intersection(set(user_groups)) @@ -372,15 +358,12 @@ class GroupRequiredMixin(AccessMixin): if not in_group: return self.handle_no_permission(request) - return super(GroupRequiredMixin, self).dispatch( - request, *args, **kwargs - ) + return super().dispatch(request, *args, **kwargs) class UserPassesTestMixin(AccessMixin): """ - CBV Mixin allows you to define test that every user should pass - to get access into view. + User must pass a test before being allowed access to the view. Class Settings `test_func` - This is required to be a method that takes user @@ -392,10 +375,8 @@ class UserPassesTestMixin(AccessMixin): def test_func(self, user): raise NotImplementedError( - "{0} is missing implementation of the " - "test_func method. You should write one.".format( - self.__class__.__name__ - ) + f"{self._class_name} is missing implementation of the " + "`test_func` method. A function to test the user is required." ) def get_test_func(self): @@ -407,52 +388,44 @@ class UserPassesTestMixin(AccessMixin): if not user_test_result: return self.handle_no_permission(request) - return super(UserPassesTestMixin, self).dispatch( - request, *args, **kwargs - ) + return super().dispatch(request, *args, **kwargs) class SuperuserRequiredMixin(AccessMixin): """ - Mixin allows you to require a user with `is_superuser` set to True. + Require users to be superusers to access the view. """ def dispatch(self, request, *args, **kwargs): if not request.user.is_superuser: return self.handle_no_permission(request) - return super(SuperuserRequiredMixin, self).dispatch( - request, *args, **kwargs - ) + return super().dispatch(request, *args, **kwargs) class StaffuserRequiredMixin(AccessMixin): """ - Mixin allows you to require a user with `is_staff` set to True. + Require users to be marked as staff to access the view. """ def dispatch(self, request, *args, **kwargs): if not request.user.is_staff: return self.handle_no_permission(request) - return super(StaffuserRequiredMixin, self).dispatch( - request, *args, **kwargs - ) + return super().dispatch(request, *args, **kwargs) -class SSLRequiredMixin(object): +class SSLRequiredMixin: """ - Simple mixin that allows you to force a view to be accessed - via https. + Require requests to be made over a secure connection. """ - raise_exception = False # Default whether to raise an exception to none + raise_exception = False def dispatch(self, request, *args, **kwargs): if getattr(settings, "DEBUG", False): - return super(SSLRequiredMixin, self).dispatch( - request, *args, **kwargs - ) + # Don't enforce the check during development + return super().dispatch(request, *args, **kwargs) if not request.is_secure(): if self.raise_exception: @@ -467,25 +440,23 @@ class SSLRequiredMixin(object): def _build_https_url(self, request): """Get the full url, replace http with https""" url = request.build_absolute_uri(request.get_full_path()) - return re.sub(r"^http", "https", url) + return urllib.parse.urlunsplit( + ("https",)+urllib.parse.urlsplit(url)[1:] + ) class RecentLoginRequiredMixin(LoginRequiredMixin): """ - Mixin allows you to require a login to be within a number of seconds. + Require the user to have logged in within a number of seconds. """ max_last_login_delta = 1800 # Defaults to 30 minutes def dispatch(self, request, *args, **kwargs): - resp = super(RecentLoginRequiredMixin, self).dispatch( - request, *args, **kwargs - ) + resp = super().dispatch(request, *args, **kwargs) if resp.status_code == 200: delta = datetime.timedelta(seconds=self.max_last_login_delta) if now() > (request.user.last_login + delta): return logout_then_login(request, self.get_login_url()) - else: - return resp return resp Index: django-braces-1.15.0/braces/views/_ajax.py =================================================================== --- django-braces-1.15.0.orig/braces/views/_ajax.py +++ django-braces-1.15.0/braces/views/_ajax.py @@ -5,10 +5,12 @@ from django.core.serializers.json import from django.http import HttpResponse, HttpResponseBadRequest -class JSONResponseMixin(object): +class JSONResponseMixin: """ - A mixin that allows you to easily serialize simple data such as a dict or - Django models. + Basic serialized responses. + + For anything more complicated than basic Python types or Django + models, please use something like django-rest-framework. """ content_type = None @@ -19,24 +21,22 @@ class JSONResponseMixin(object): if self.content_type is not None and not isinstance( self.content_type, str ): + class_name = self.__class__.__name__ raise ImproperlyConfigured( - "{0} is missing a content type. Define {0}.content_type, " - "or override {0}.get_content_type().".format( - self.__class__.__name__ - ) + f"{class_name} is missing a content type. Define {class_name}" + ".content_type or override {class_name}.get_content_type()." ) 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 + dumps_kwargs = getattr(self, "json_dumps_kwargs", None) or {} + dumps_kwargs.setdefault("ensure_ascii", False) + return 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. + Limited serialization for shipping plain data. + Do not use for models or other complex objects. """ json_context = json.dumps( context_dict, @@ -56,7 +56,7 @@ class JSONResponseMixin(object): return HttpResponse(json_data, content_type=self.get_content_type()) -class AjaxResponseMixin(object): +class AjaxResponseMixin: """ 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, @@ -64,12 +64,13 @@ class AjaxResponseMixin(object): """ def dispatch(self, request, *args, **kwargs): - request_method = request.method.lower() - - if request.is_ajax() and request_method in self.http_method_names: + if all([ + request.headers.get("x-requested-with") == "XMLHttpRequest", + request.method.lower() in self.http_method_names + ]): handler = getattr( self, - "{0}_ajax".format(request_method), + f"{request.method.lower()}_ajax", self.http_method_not_allowed, ) self.request = request @@ -77,9 +78,7 @@ class AjaxResponseMixin(object): self.kwargs = kwargs return handler(request, *args, **kwargs) - return super(AjaxResponseMixin, self).dispatch( - request, *args, **kwargs - ) + return super().dispatch(request, *args, **kwargs) def get_ajax(self, request, *args, **kwargs): return self.get(request, *args, **kwargs) @@ -96,9 +95,11 @@ class AjaxResponseMixin(object): class JsonRequestResponseMixin(JSONResponseMixin): """ - Extends JSONResponseMixin. Attempts to parse request as JSON. If request - is properly formatted, the json is saved to self.request_json as a Python - object. request_json will be None for imparsible requests. + Attempt to parse the request body as JSON. + + If successful, self.request_json will contain the deserialized object. + Otherwise, self.request_json will be None. + Set the attribute require_json to True to return a 400 "Bad Request" error for requests that don't contain JSON. @@ -132,7 +133,7 @@ class JsonRequestResponseMixin(JSONRespo def get_request_json(self): try: return json.loads(self.request.body.decode("utf-8")) - except ValueError: + except (json.JSONDecodeError, ValueError): return None def dispatch(self, request, *args, **kwargs): @@ -149,9 +150,7 @@ class JsonRequestResponseMixin(JSONRespo ] ): return self.render_bad_request_response() - return super(JsonRequestResponseMixin, self).dispatch( - request, *args, **kwargs - ) + return super().dispatch(request, *args, **kwargs) class JSONRequestResponseMixin(JsonRequestResponseMixin): Index: django-braces-1.15.0/braces/views/_forms.py =================================================================== --- django-braces-1.15.0.orig/braces/views/_forms.py +++ django-braces-1.15.0/braces/views/_forms.py @@ -9,7 +9,7 @@ from django.views.decorators.csrf import from django.urls import reverse -class CsrfExemptMixin(object): +class CsrfExemptMixin: """ Exempts the view from CSRF requirements. @@ -19,31 +19,32 @@ class CsrfExemptMixin(object): @method_decorator(csrf_exempt) def dispatch(self, *args, **kwargs): - return super(CsrfExemptMixin, self).dispatch(*args, **kwargs) + return super().dispatch(*args, **kwargs) -class UserFormKwargsMixin(object): +class UserFormKwargsMixin: """ - CBV mixin which puts the user from the request into the form kwargs. - Note: Using this mixin requires you to pop the `user` kwarg - out of the dict in the super of your form's `__init__`. + Automatically include `request.user` in form kwargs. + + ## Note + You will need to handle the `user` kwarg in your form. Usually + this means `user = kwargs.pop("user")` in your form's `__init__`. """ def get_form_kwargs(self): - kwargs = super(UserFormKwargsMixin, self).get_form_kwargs() + kwargs = super().get_form_kwargs() # Update the existing form kwargs dict with the request's user. kwargs.update({"user": self.request.user}) return kwargs -class SuccessURLRedirectListMixin(object): +class SuccessURLRedirectListMixin: """ - Simple CBV mixin which sets the success url to the list view of - a given app. Set success_list_url as a class attribute of your - CBV and don't worry about overloading the get_success_url. + Automatically reverses `success_list_url` and returns that as + the `success_url` for a form view. - This is only to be used for redirecting to a list page. If you need - to reverse the url with kwargs, this is not the mixin to use. + This is meant to redirect to a view without arguments. If you need + to include arguments to `reverse`, you can omit this mixin. """ success_list_url = None # Default the success url to none @@ -51,19 +52,20 @@ class SuccessURLRedirectListMixin(object def get_success_url(self): # Return the reversed success url. if self.success_list_url is None: + class_name = self.__class__.__name__ raise ImproperlyConfigured( - "{0} is missing a success_list_url " - "name to reverse and redirect to. Define " - "{0}.success_list_url or override " - "{0}.get_success_url().".format(self.__class__.__name__) + f"{class_name} is missing a success_list_url attribute. " + f"Define {class_name}.success_list_url or override " + f"{class_name}.get_success_url()." ) return reverse(self.success_list_url) -class _MessageAPIWrapper(object): +class _MessageAPIWrapper: """ - Wrap the django.contrib.messages.api module to automatically pass a given - request object as the first parameter of function calls. + Wrapper for the django.contrib.messages.api module. + Automatically pass a request object as the first parameter of + message function calls. """ API = set( @@ -86,59 +88,59 @@ class _MessageAPIWrapper(object): setattr(self, name, partial(api_fn, request)) -class _MessageDescriptor(object): +class _MessageDescriptor: """ A descriptor that binds the _MessageAPIWrapper to the view's request. """ - def __get__(self, instance, owner): + def __get__(self, instance, *args, **kwargs): return _MessageAPIWrapper(instance.request) -class MessageMixin(object): +class MessageMixin: """ Add a `messages` attribute on the view instance that wraps - `django.contrib .messages`, automatically passing the current + `django.contrib.messages`, automatically passing the current request object. """ messages = _MessageDescriptor() + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self._class_name = self.__class__.__name__ + class FormValidMessageMixin(MessageMixin): """ - Mixin allows you to set static message which is displayed by - Django's messages framework through a static property on the class - or programmatically by overloading the get_form_valid_message method. + Set a string to be sent via Django's messages framework when a form + passes validation. """ form_valid_message = None # Default to None def get_form_valid_message(self): """ - Validate that form_valid_message is set and is either a - unicode or str object. + Validate that form_valid_message is set correctly """ if self.form_valid_message is None: raise ImproperlyConfigured( - "{0}.form_valid_message is not set. Define " - "{0}.form_valid_message, or override " - "{0}.get_form_valid_message().".format(self.__class__.__name__) + f"{self._class_name}.form_valid_message is not set. Define " + f"{self._class_name}.form_valid_message, or override " + f"{self._class_name}.get_form_valid_message()." ) if not isinstance(self.form_valid_message, (str, Promise)): raise ImproperlyConfigured( - "{0}.form_valid_message must be a str or unicode " - "object.".format(self.__class__.__name__) + f"{self._class_name}.form_valid_message must be a str or Promise." ) return force_str(self.form_valid_message) def form_valid(self, form): """ - Call the super first, so that when overriding - get_form_valid_message, we have access to the newly saved object. + Set the "form valid" message for standard form validation """ response = super(FormValidMessageMixin, self).form_valid(form) self.messages.success( @@ -147,6 +149,9 @@ class FormValidMessageMixin(MessageMixin return response def delete(self, *args, **kwargs): + """ + Set the "form valid" message for delete form validation + """ response = super(FormValidMessageMixin, self).delete(*args, **kwargs) self.messages.success( self.get_form_valid_message(), fail_silently=True @@ -156,36 +161,34 @@ class FormValidMessageMixin(MessageMixin class FormInvalidMessageMixin(MessageMixin): """ - Mixin allows you to set static message which is displayed by - Django's messages framework through a static property on the class - or programmatically by overloading the get_form_invalid_message method. + Set a string to be sent via Django's messages framework when a form + fails validation. """ form_invalid_message = None def get_form_invalid_message(self): """ - Validate that form_invalid_message is set and is either a - unicode or str object. + Validate that form_invalid_message is set correctly. """ if self.form_invalid_message is None: raise ImproperlyConfigured( - "{0}.form_invalid_message is not set. Define " - "{0}.form_invalid_message, or override " - "{0}.get_form_invalid_message().".format( - self.__class__.__name__ - ) + f"{self._class_name}.form_invalid_message is not set. Define " + f"{self._class_name}.form_invalid_message, or override " + f"{self._class_name}.get_form_invalid_message()." ) if not isinstance(self.form_invalid_message, (str, Promise)): raise ImproperlyConfigured( - "{0}.form_invalid_message must be a str or unicode " - "object.".format(self.__class__.__name__) + f"{self._class_name}.form_invalid_message must be a str or Promise." ) return force_str(self.form_invalid_message) def form_invalid(self, form): + """ + Set the "form invalid" message for standard form validation + """ response = super(FormInvalidMessageMixin, self).form_invalid(form) self.messages.error( self.get_form_invalid_message(), fail_silently=True @@ -195,8 +198,5 @@ class FormInvalidMessageMixin(MessageMix class FormMessagesMixin(FormValidMessageMixin, FormInvalidMessageMixin): """ - Mixin is a shortcut to use both FormValidMessageMixin and - FormInvalidMessageMixin. + Set messages to be sent whether a form is valid or invalid. """ - - pass Index: django-braces-1.15.0/braces/views/_other.py =================================================================== --- django-braces-1.15.0.orig/braces/views/_other.py +++ django-braces-1.15.0/braces/views/_other.py @@ -101,9 +101,7 @@ class CanonicalSlugDetailMixin(object): } return redirect(current_urlpattern, **params) - return super(CanonicalSlugDetailMixin, self).dispatch( - request, *args, **kwargs - ) + return super().dispatch(request, *args, **kwargs) def get_canonical_slug(self): """ @@ -116,11 +114,11 @@ class CanonicalSlugDetailMixin(object): return self.get_object().slug -class AllVerbsMixin(object): +class AllVerbsMixin: """Call a single method for all HTTP verbs. The name of the method should be specified using the class attribute - ``all_handler``. The default value of this attribute is 'all'. + `all_handler`. The default value of this attribute is 'all'. """ all_handler = "all" @@ -128,18 +126,16 @@ class AllVerbsMixin(object): def dispatch(self, request, *args, **kwargs): if not self.all_handler: raise ImproperlyConfigured( - "{0} requires the all_handler attribute to be set.".format( - self.__class__.__name__ - ) + f"{self.__class__.__name__} requires the all_handler attribute to be set." ) handler = getattr(self, self.all_handler, self.http_method_not_allowed) return handler(request, *args, **kwargs) -class HeaderMixin(object): +class HeaderMixin: """ - Add arbitrary HTTP headers to a response by specifying them in the + Add extra HTTP headers to a response by specifying them in the ``headers`` attribute or by overriding the ``get_headers()`` method. """ Index: django-braces-1.15.0/braces/views/_queries.py =================================================================== --- django-braces-1.15.0.orig/braces/views/_queries.py +++ django-braces-1.15.0/braces/views/_queries.py @@ -3,10 +3,9 @@ import warnings from django.core.exceptions import ImproperlyConfigured -class SelectRelatedMixin(object): +class SelectRelatedMixin: """ - Mixin allows you to provide a tuple or list of related models to - perform a select_related on. + Automatically apply `select_related` for a list of relations. """ select_related = None # Default related fields to none @@ -15,20 +14,19 @@ class SelectRelatedMixin(object): if self.select_related is None: # If no fields were provided, raise a configuration error raise ImproperlyConfigured( - "{0} is missing the select_related property. This must be " - "a tuple or list.".format(self.__class__.__name__) + f"{self.__class__.__name__} is missing the select_related attribute." ) if not isinstance(self.select_related, (tuple, list)): # If the select_related argument is *not* a tuple or list, # raise a configuration error. raise ImproperlyConfigured( - "{0}'s select_related property must be a tuple or " - "list.".format(self.__class__.__name__) + f"{self.__class__.__name__}'s select_related property must be " + "a tuple or list." ) # Get the current queryset of the view - queryset = super(SelectRelatedMixin, self).get_queryset() + queryset = super().get_queryset() if not self.select_related: warnings.warn("The select_related attribute is empty") @@ -37,10 +35,9 @@ class SelectRelatedMixin(object): return queryset.select_related(*self.select_related) -class PrefetchRelatedMixin(object): +class PrefetchRelatedMixin: """ - Mixin allows you to provide a tuple or list of related models to - perform a prefetch_related on. + Automatically apply `prefetch_related` for a list of relations. """ prefetch_related = None # Default prefetch fields to none @@ -49,20 +46,18 @@ class PrefetchRelatedMixin(object): if self.prefetch_related is None: # If no fields were provided, raise a configuration error raise ImproperlyConfigured( - "{0} is missing the prefetch_related property. This must be " - "a tuple or list.".format(self.__class__.__name__) + f"{self.__class__.__name__} is missing the prefetch_related attribute." ) if not isinstance(self.prefetch_related, (tuple, list)): # If the prefetch_related argument is *not* a tuple or list, # raise a configuration error. raise ImproperlyConfigured( - "{0}'s prefetch_related property must be a tuple or " - "list.".format(self.__class__.__name__) + f"{self.__class__.__name__}'s prefetch_related property must be a tuple or list." ) # Get the current queryset of the view - queryset = super(PrefetchRelatedMixin, self).get_queryset() + queryset = super().get_queryset() if not self.prefetch_related: warnings.warn("The prefetch_related attribute is empty") @@ -71,9 +66,9 @@ class PrefetchRelatedMixin(object): return queryset.prefetch_related(*self.prefetch_related) -class OrderableListMixin(object): +class OrderableListMixin: """ - Mixin allows your users to order records using GET parameters + Order the queryset based on GET parameters. """ orderable_columns = None @@ -89,7 +84,7 @@ class OrderableListMixin(object): * ``order_by`` - name of the field * ``ordering`` - order of ordering, either ``asc`` or ``desc`` """ - context = super(OrderableListMixin, self).get_context_data(**kwargs) + context = super().get_context_data(**kwargs) context["order_by"] = self.order_by context["ordering"] = self.ordering return context @@ -97,18 +92,14 @@ class OrderableListMixin(object): def get_orderable_columns(self): if not self.orderable_columns: raise ImproperlyConfigured( - "{0} needs the ordering columns defined.".format( - self.__class__.__name__ - ) + f"{self.__class__.__name__} needs the ordering columns defined." ) return self.orderable_columns def get_orderable_columns_default(self): if not self.orderable_columns_default: raise ImproperlyConfigured( - "{0} needs the default ordering column defined.".format( - self.__class__.__name__ - ) + f"{self.__class__.__name__} needs the default ordering column defined." ) return self.orderable_columns_default @@ -118,9 +109,7 @@ class OrderableListMixin(object): else: if self.ordering_default not in ["asc", "desc"]: raise ImproperlyConfigured( - "{0} only allows asc or desc as ordering option".format( - self.__class__.__name__ - ) + f"{self.__class__.__name__} only allows asc or desc as ordering option" ) return self.ordering_default @@ -141,11 +130,10 @@ class OrderableListMixin(object): self.order_by = order_by self.ordering = self.get_ordering_default() - if ( - order_by - and self.request.GET.get("ordering", self.ordering) == "desc" - ): - order_by = "-" + order_by + if all([order_by, + self.request.GET.get("ordering", self.ordering) == "desc" + ]): + order_by = f"-{order_by}" self.ordering = self.request.GET.get("ordering", self.ordering) return queryset.order_by(order_by) @@ -154,5 +142,5 @@ class OrderableListMixin(object): """ Returns ordered ``QuerySet`` """ - unordered_queryset = super(OrderableListMixin, self).get_queryset() + unordered_queryset = super().get_queryset() return self.get_ordered_queryset(unordered_queryset) Index: django-braces-1.15.0/tests/test_other_mixins.py =================================================================== --- django-braces-1.15.0.orig/tests/test_other_mixins.py +++ django-braces-1.15.0/tests/test_other_mixins.py @@ -562,7 +562,7 @@ class TestModelCanonicalSlugDetailView(t class MessageMixinTests(test.TestCase): def setUp(self): self.rf = test.RequestFactory() - self.middleware = MessageMiddleware() + self.middleware = MessageMiddleware("") def get_request(self, *args, **kwargs): request = self.rf.get("/")
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor