测试gitnore
This commit is contained in:
@@ -2,16 +2,10 @@ from django.contrib.messages import constants
|
||||
from django.contrib.messages.storage import default_storage
|
||||
|
||||
__all__ = (
|
||||
"add_message",
|
||||
"get_messages",
|
||||
"get_level",
|
||||
"set_level",
|
||||
"debug",
|
||||
"info",
|
||||
"success",
|
||||
"warning",
|
||||
"error",
|
||||
"MessageFailure",
|
||||
'add_message', 'get_messages',
|
||||
'get_level', 'set_level',
|
||||
'debug', 'info', 'success', 'warning', 'error',
|
||||
'MessageFailure',
|
||||
)
|
||||
|
||||
|
||||
@@ -19,22 +13,22 @@ class MessageFailure(Exception):
|
||||
pass
|
||||
|
||||
|
||||
def add_message(request, level, message, extra_tags="", fail_silently=False):
|
||||
def add_message(request, level, message, extra_tags='', fail_silently=False):
|
||||
"""
|
||||
Attempt to add a message to the request using the 'messages' app.
|
||||
"""
|
||||
try:
|
||||
messages = request._messages
|
||||
except AttributeError:
|
||||
if not hasattr(request, "META"):
|
||||
if not hasattr(request, 'META'):
|
||||
raise TypeError(
|
||||
"add_message() argument must be an HttpRequest object, not "
|
||||
"'%s'." % request.__class__.__name__
|
||||
)
|
||||
if not fail_silently:
|
||||
raise MessageFailure(
|
||||
"You cannot add messages without installing "
|
||||
"django.contrib.messages.middleware.MessageMiddleware"
|
||||
'You cannot add messages without installing '
|
||||
'django.contrib.messages.middleware.MessageMiddleware'
|
||||
)
|
||||
else:
|
||||
return messages.add(level, message, extra_tags)
|
||||
@@ -45,7 +39,7 @@ def get_messages(request):
|
||||
Return the message storage on the request if it exists, otherwise return
|
||||
an empty list.
|
||||
"""
|
||||
return getattr(request, "_messages", [])
|
||||
return getattr(request, '_messages', [])
|
||||
|
||||
|
||||
def get_level(request):
|
||||
@@ -55,7 +49,7 @@ def get_level(request):
|
||||
The default level is the ``MESSAGE_LEVEL`` setting. If this is not found,
|
||||
use the ``INFO`` level.
|
||||
"""
|
||||
storage = getattr(request, "_messages", default_storage(request))
|
||||
storage = getattr(request, '_messages', default_storage(request))
|
||||
return storage.level
|
||||
|
||||
|
||||
@@ -66,62 +60,37 @@ def set_level(request, level):
|
||||
|
||||
If set to ``None``, use the default level (see the get_level() function).
|
||||
"""
|
||||
if not hasattr(request, "_messages"):
|
||||
if not hasattr(request, '_messages'):
|
||||
return False
|
||||
request._messages.level = level
|
||||
return True
|
||||
|
||||
|
||||
def debug(request, message, extra_tags="", fail_silently=False):
|
||||
def debug(request, message, extra_tags='', fail_silently=False):
|
||||
"""Add a message with the ``DEBUG`` level."""
|
||||
add_message(
|
||||
request,
|
||||
constants.DEBUG,
|
||||
message,
|
||||
extra_tags=extra_tags,
|
||||
fail_silently=fail_silently,
|
||||
)
|
||||
add_message(request, constants.DEBUG, message, extra_tags=extra_tags,
|
||||
fail_silently=fail_silently)
|
||||
|
||||
|
||||
def info(request, message, extra_tags="", fail_silently=False):
|
||||
def info(request, message, extra_tags='', fail_silently=False):
|
||||
"""Add a message with the ``INFO`` level."""
|
||||
add_message(
|
||||
request,
|
||||
constants.INFO,
|
||||
message,
|
||||
extra_tags=extra_tags,
|
||||
fail_silently=fail_silently,
|
||||
)
|
||||
add_message(request, constants.INFO, message, extra_tags=extra_tags,
|
||||
fail_silently=fail_silently)
|
||||
|
||||
|
||||
def success(request, message, extra_tags="", fail_silently=False):
|
||||
def success(request, message, extra_tags='', fail_silently=False):
|
||||
"""Add a message with the ``SUCCESS`` level."""
|
||||
add_message(
|
||||
request,
|
||||
constants.SUCCESS,
|
||||
message,
|
||||
extra_tags=extra_tags,
|
||||
fail_silently=fail_silently,
|
||||
)
|
||||
add_message(request, constants.SUCCESS, message, extra_tags=extra_tags,
|
||||
fail_silently=fail_silently)
|
||||
|
||||
|
||||
def warning(request, message, extra_tags="", fail_silently=False):
|
||||
def warning(request, message, extra_tags='', fail_silently=False):
|
||||
"""Add a message with the ``WARNING`` level."""
|
||||
add_message(
|
||||
request,
|
||||
constants.WARNING,
|
||||
message,
|
||||
extra_tags=extra_tags,
|
||||
fail_silently=fail_silently,
|
||||
)
|
||||
add_message(request, constants.WARNING, message, extra_tags=extra_tags,
|
||||
fail_silently=fail_silently)
|
||||
|
||||
|
||||
def error(request, message, extra_tags="", fail_silently=False):
|
||||
def error(request, message, extra_tags='', fail_silently=False):
|
||||
"""Add a message with the ``ERROR`` level."""
|
||||
add_message(
|
||||
request,
|
||||
constants.ERROR,
|
||||
message,
|
||||
extra_tags=extra_tags,
|
||||
fail_silently=fail_silently,
|
||||
)
|
||||
add_message(request, constants.ERROR, message, extra_tags=extra_tags,
|
||||
fail_silently=fail_silently)
|
||||
|
||||
@@ -3,5 +3,5 @@ from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
class MessagesConfig(AppConfig):
|
||||
name = "django.contrib.messages"
|
||||
name = 'django.contrib.messages'
|
||||
verbose_name = _("Messages")
|
||||
|
||||
@@ -5,17 +5,17 @@ WARNING = 30
|
||||
ERROR = 40
|
||||
|
||||
DEFAULT_TAGS = {
|
||||
DEBUG: "debug",
|
||||
INFO: "info",
|
||||
SUCCESS: "success",
|
||||
WARNING: "warning",
|
||||
ERROR: "error",
|
||||
DEBUG: 'debug',
|
||||
INFO: 'info',
|
||||
SUCCESS: 'success',
|
||||
WARNING: 'warning',
|
||||
ERROR: 'error',
|
||||
}
|
||||
|
||||
DEFAULT_LEVELS = {
|
||||
"DEBUG": DEBUG,
|
||||
"INFO": INFO,
|
||||
"SUCCESS": SUCCESS,
|
||||
"WARNING": WARNING,
|
||||
"ERROR": ERROR,
|
||||
'DEBUG': DEBUG,
|
||||
'INFO': INFO,
|
||||
'SUCCESS': SUCCESS,
|
||||
'WARNING': WARNING,
|
||||
'ERROR': ERROR,
|
||||
}
|
||||
|
||||
@@ -8,6 +8,6 @@ def messages(request):
|
||||
'DEFAULT_MESSAGE_LEVELS'.
|
||||
"""
|
||||
return {
|
||||
"messages": get_messages(request),
|
||||
"DEFAULT_MESSAGE_LEVELS": DEFAULT_LEVELS,
|
||||
'messages': get_messages(request),
|
||||
'DEFAULT_MESSAGE_LEVELS': DEFAULT_LEVELS,
|
||||
}
|
||||
|
||||
@@ -19,8 +19,8 @@ class MessageMiddleware(MiddlewareMixin):
|
||||
"""
|
||||
# A higher middleware layer may return a request which does not contain
|
||||
# messages storage, so make no assumption that it will be there.
|
||||
if hasattr(request, "_messages"):
|
||||
if hasattr(request, '_messages'):
|
||||
unstored_messages = request._messages.update(response)
|
||||
if unstored_messages and settings.DEBUG:
|
||||
raise ValueError("Not all temporary messages could be stored.")
|
||||
raise ValueError('Not all temporary messages could be stored.')
|
||||
return response
|
||||
|
||||
@@ -34,11 +34,11 @@ class Message:
|
||||
|
||||
@property
|
||||
def tags(self):
|
||||
return " ".join(tag for tag in [self.extra_tags, self.level_tag] if tag)
|
||||
return ' '.join(tag for tag in [self.extra_tags, self.level_tag] if tag)
|
||||
|
||||
@property
|
||||
def level_tag(self):
|
||||
return LEVEL_TAGS.get(self.level, "")
|
||||
return LEVEL_TAGS.get(self.level, '')
|
||||
|
||||
|
||||
class BaseStorage:
|
||||
@@ -69,16 +69,13 @@ class BaseStorage:
|
||||
def __contains__(self, item):
|
||||
return item in self._loaded_messages or item in self._queued_messages
|
||||
|
||||
def __repr__(self):
|
||||
return f"<{self.__class__.__qualname__}: request={self.request!r}>"
|
||||
|
||||
@property
|
||||
def _loaded_messages(self):
|
||||
"""
|
||||
Return a list of loaded messages, retrieving them first if they have
|
||||
not been loaded yet.
|
||||
"""
|
||||
if not hasattr(self, "_loaded_data"):
|
||||
if not hasattr(self, '_loaded_data'):
|
||||
messages, all_retrieved = self._get()
|
||||
self._loaded_data = messages or []
|
||||
return self._loaded_data
|
||||
@@ -96,9 +93,7 @@ class BaseStorage:
|
||||
just containing no messages) then ``None`` should be returned in
|
||||
place of ``messages``.
|
||||
"""
|
||||
raise NotImplementedError(
|
||||
"subclasses of BaseStorage must provide a _get() method"
|
||||
)
|
||||
raise NotImplementedError('subclasses of BaseStorage must provide a _get() method')
|
||||
|
||||
def _store(self, messages, response, *args, **kwargs):
|
||||
"""
|
||||
@@ -109,9 +104,7 @@ class BaseStorage:
|
||||
|
||||
**This method must be implemented by a subclass.**
|
||||
"""
|
||||
raise NotImplementedError(
|
||||
"subclasses of BaseStorage must provide a _store() method"
|
||||
)
|
||||
raise NotImplementedError('subclasses of BaseStorage must provide a _store() method')
|
||||
|
||||
def _prepare_messages(self, messages):
|
||||
"""
|
||||
@@ -134,7 +127,7 @@ class BaseStorage:
|
||||
messages = self._loaded_messages + self._queued_messages
|
||||
return self._store(messages, response)
|
||||
|
||||
def add(self, level, message, extra_tags=""):
|
||||
def add(self, level, message, extra_tags=''):
|
||||
"""
|
||||
Queue a message to be stored.
|
||||
|
||||
@@ -159,8 +152,8 @@ class BaseStorage:
|
||||
The default level is the ``MESSAGE_LEVEL`` setting. If this is
|
||||
not found, the ``INFO`` level is used.
|
||||
"""
|
||||
if not hasattr(self, "_level"):
|
||||
self._level = getattr(settings, "MESSAGE_LEVEL", constants.INFO)
|
||||
if not hasattr(self, '_level'):
|
||||
self._level = getattr(settings, 'MESSAGE_LEVEL', constants.INFO)
|
||||
return self._level
|
||||
|
||||
def _set_level(self, value=None):
|
||||
@@ -170,7 +163,7 @@ class BaseStorage:
|
||||
If set to ``None``, the default level will be used (see the
|
||||
``_get_level`` method).
|
||||
"""
|
||||
if value is None and hasattr(self, "_level"):
|
||||
if value is None and hasattr(self, '_level'):
|
||||
del self._level
|
||||
else:
|
||||
self._level = int(value)
|
||||
|
||||
@@ -5,6 +5,7 @@ from django.conf import settings
|
||||
from django.contrib.messages.storage.base import BaseStorage, Message
|
||||
from django.core import signing
|
||||
from django.http import SimpleCookie
|
||||
from django.utils.crypto import constant_time_compare, salted_hmac
|
||||
from django.utils.safestring import SafeData, mark_safe
|
||||
|
||||
|
||||
@@ -12,8 +13,7 @@ class MessageEncoder(json.JSONEncoder):
|
||||
"""
|
||||
Compactly serialize instances of the ``Message`` class as JSON.
|
||||
"""
|
||||
|
||||
message_key = "__json_message"
|
||||
message_key = '__json_message'
|
||||
|
||||
def default(self, obj):
|
||||
if isinstance(obj, Message):
|
||||
@@ -39,7 +39,8 @@ class MessageDecoder(json.JSONDecoder):
|
||||
return Message(*obj[2:])
|
||||
return [self.process_messages(item) for item in obj]
|
||||
if isinstance(obj, dict):
|
||||
return {key: self.process_messages(value) for key, value in obj.items()}
|
||||
return {key: self.process_messages(value)
|
||||
for key, value in obj.items()}
|
||||
return obj
|
||||
|
||||
def decode(self, s, **kwargs):
|
||||
@@ -51,26 +52,25 @@ class MessageSerializer:
|
||||
def dumps(self, obj):
|
||||
return json.dumps(
|
||||
obj,
|
||||
separators=(",", ":"),
|
||||
separators=(',', ':'),
|
||||
cls=MessageEncoder,
|
||||
).encode("latin-1")
|
||||
).encode('latin-1')
|
||||
|
||||
def loads(self, data):
|
||||
return json.loads(data.decode("latin-1"), cls=MessageDecoder)
|
||||
return json.loads(data.decode('latin-1'), cls=MessageDecoder)
|
||||
|
||||
|
||||
class CookieStorage(BaseStorage):
|
||||
"""
|
||||
Store messages in a cookie.
|
||||
"""
|
||||
|
||||
cookie_name = "messages"
|
||||
cookie_name = 'messages'
|
||||
# uwsgi's default configuration enforces a maximum size of 4kb for all the
|
||||
# HTTP headers. In order to leave some room for other cookies and headers,
|
||||
# restrict the session cookie to 1/2 of 4kb. See #18781.
|
||||
max_cookie_size = 2048
|
||||
not_finished = "__messagesnotfinished__"
|
||||
key_salt = "django.contrib.messages"
|
||||
not_finished = '__messagesnotfinished__'
|
||||
key_salt = 'django.contrib.messages'
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
@@ -98,8 +98,7 @@ class CookieStorage(BaseStorage):
|
||||
"""
|
||||
if encoded_data:
|
||||
response.set_cookie(
|
||||
self.cookie_name,
|
||||
encoded_data,
|
||||
self.cookie_name, encoded_data,
|
||||
domain=settings.SESSION_COOKIE_DOMAIN,
|
||||
secure=settings.SESSION_COOKIE_SECURE or None,
|
||||
httponly=settings.SESSION_COOKIE_HTTPONLY or None,
|
||||
@@ -136,12 +135,23 @@ class CookieStorage(BaseStorage):
|
||||
unstored_messages.append(messages.pop(0))
|
||||
else:
|
||||
unstored_messages.insert(0, messages.pop())
|
||||
encoded_data = self._encode(
|
||||
messages + [self.not_finished], encode_empty=unstored_messages
|
||||
)
|
||||
encoded_data = self._encode(messages + [self.not_finished],
|
||||
encode_empty=unstored_messages)
|
||||
self._update_cookie(encoded_data, response)
|
||||
return unstored_messages
|
||||
|
||||
def _legacy_hash(self, value):
|
||||
"""
|
||||
# RemovedInDjango40Warning: pre-Django 3.1 hashes will be invalid.
|
||||
Create an HMAC/SHA1 hash based on the value and the project setting's
|
||||
SECRET_KEY, modified to make it unique for the present purpose.
|
||||
"""
|
||||
# The class wide key salt is not reused here since older Django
|
||||
# versions had it fixed and making it dynamic would break old hashes if
|
||||
# self.key_salt is changed.
|
||||
key_salt = 'django.contrib.messages'
|
||||
return salted_hmac(key_salt, value).hexdigest()
|
||||
|
||||
def _encode(self, messages, encode_empty=False):
|
||||
"""
|
||||
Return an encoded version of the messages list which can be stored as
|
||||
@@ -151,9 +161,7 @@ class CookieStorage(BaseStorage):
|
||||
also contains a hash to ensure that the data was not tampered with.
|
||||
"""
|
||||
if messages or encode_empty:
|
||||
return self.signer.sign_object(
|
||||
messages, serializer=MessageSerializer, compress=True
|
||||
)
|
||||
return self.signer.sign_object(messages, serializer=MessageSerializer, compress=True)
|
||||
|
||||
def _decode(self, data):
|
||||
"""
|
||||
@@ -171,7 +179,10 @@ class CookieStorage(BaseStorage):
|
||||
# except (signing.BadSignature, json.JSONDecodeError):
|
||||
# pass
|
||||
except signing.BadSignature:
|
||||
decoded = None
|
||||
# RemovedInDjango40Warning: when the deprecation ends, replace
|
||||
# with:
|
||||
# decoded = None.
|
||||
decoded = self._legacy_decode(data)
|
||||
except (binascii.Error, json.JSONDecodeError):
|
||||
decoded = self.signer.unsign(data)
|
||||
|
||||
@@ -185,3 +196,12 @@ class CookieStorage(BaseStorage):
|
||||
# with the data.
|
||||
self.used = True
|
||||
return None
|
||||
|
||||
def _legacy_decode(self, data):
|
||||
# RemovedInDjango40Warning: pre-Django 3.1 hashes will be invalid.
|
||||
bits = data.split('$', 1)
|
||||
if len(bits) == 2:
|
||||
hash_, value = bits
|
||||
if constant_time_compare(hash_, self._legacy_hash(value)):
|
||||
return value
|
||||
return None
|
||||
|
||||
@@ -8,14 +8,12 @@ class FallbackStorage(BaseStorage):
|
||||
Try to store all messages in the first backend. Store any unstored
|
||||
messages in each subsequent backend.
|
||||
"""
|
||||
|
||||
storage_classes = (CookieStorage, SessionStorage)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.storages = [
|
||||
storage_class(*args, **kwargs) for storage_class in self.storage_classes
|
||||
]
|
||||
self.storages = [storage_class(*args, **kwargs)
|
||||
for storage_class in self.storage_classes]
|
||||
self._used_storages = set()
|
||||
|
||||
def _get(self, *args, **kwargs):
|
||||
|
||||
@@ -1,24 +1,22 @@
|
||||
import json
|
||||
|
||||
from django.contrib.messages.storage.base import BaseStorage
|
||||
from django.contrib.messages.storage.cookie import MessageDecoder, MessageEncoder
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
from django.contrib.messages.storage.cookie import (
|
||||
MessageDecoder, MessageEncoder,
|
||||
)
|
||||
|
||||
|
||||
class SessionStorage(BaseStorage):
|
||||
"""
|
||||
Store messages in the session (that is, django.contrib.sessions).
|
||||
"""
|
||||
|
||||
session_key = "_messages"
|
||||
session_key = '_messages'
|
||||
|
||||
def __init__(self, request, *args, **kwargs):
|
||||
if not hasattr(request, "session"):
|
||||
raise ImproperlyConfigured(
|
||||
"The session-based temporary message storage requires session "
|
||||
"middleware to be installed, and come before the message "
|
||||
"middleware in the MIDDLEWARE list."
|
||||
)
|
||||
assert hasattr(request, 'session'), "The session-based temporary "\
|
||||
"message storage requires session middleware to be installed, "\
|
||||
"and come before the message middleware in the "\
|
||||
"MIDDLEWARE list."
|
||||
super().__init__(request, *args, **kwargs)
|
||||
|
||||
def _get(self, *args, **kwargs):
|
||||
@@ -27,10 +25,7 @@ class SessionStorage(BaseStorage):
|
||||
always stores everything it is given, so return True for the
|
||||
all_retrieved flag.
|
||||
"""
|
||||
return (
|
||||
self.deserialize_messages(self.request.session.get(self.session_key)),
|
||||
True,
|
||||
)
|
||||
return self.deserialize_messages(self.request.session.get(self.session_key)), True
|
||||
|
||||
def _store(self, messages, response, *args, **kwargs):
|
||||
"""
|
||||
|
||||
@@ -8,5 +8,5 @@ def get_level_tags():
|
||||
"""
|
||||
return {
|
||||
**constants.DEFAULT_TAGS,
|
||||
**getattr(settings, "MESSAGE_TAGS", {}),
|
||||
**getattr(settings, 'MESSAGE_TAGS', {}),
|
||||
}
|
||||
|
||||
@@ -5,8 +5,7 @@ class SuccessMessageMixin:
|
||||
"""
|
||||
Add a success message on successful form submission.
|
||||
"""
|
||||
|
||||
success_message = ""
|
||||
success_message = ''
|
||||
|
||||
def form_valid(self, form):
|
||||
response = super().form_valid(form)
|
||||
|
||||
Reference in New Issue
Block a user