Skip to content

Compatibility from django 1.4 to 1.11 with python 2.7 #12

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 28 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,33 @@
language: python
python:
- 2.6
- 2.7
- 3.6

env:
- DJANGO=1.4
- DJANGO=1.5
- DJANGO=1.6
- DJANGO=1.7
- DJANGO=1.8
- DJANGO=1.9
- DJANGO=1.10
- DJANGO=1.11
- DJANGO=2.0

matrix:
exclude:
- python: 3.6
env: DJANGO=1.4
- python: 3.6
env: DJANGO=1.5
- python: 3.6
env: DJANGO=1.6
- python: 3.6
env: DJANGO=1.7
- python: 2.7
env: DJANGO=2.0
install:
script:
- pip install Django==$DJANGO
- python setup.py develop
- ./runtests.py
script:
- python manage.py test tests
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ Fork, clone and create a virtualenv. Then run::

Run tests with::

./runtests.py
python manage.py test tests

Please submit pull requests using 'develop' as the target branch.

Expand Down
11 changes: 11 additions & 0 deletions async_messages/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
from django.contrib.messages import constants


class AsyncMessageException(Exception):
pass


def message_user(user, message, level=constants.INFO):
"""
Send a message to a particular user.
Expand All @@ -12,6 +16,10 @@ def message_user(user, message, level=constants.INFO):
"""
# We store a list of messages in the cache so we can have multiple messages
# queued up for a user.

if user.id is None:
raise AsyncMessageException('Anonymous users cannot send messages.')

user_key = _user_key(user)
messages = cache.get(user_key) or []
messages.append((message, level))
Expand All @@ -36,6 +44,9 @@ def get_messages(user):

:param user: User instance
"""
if user.id is None:
return None

key = _user_key(user)
result = cache.get(key)
if result:
Expand Down
36 changes: 34 additions & 2 deletions async_messages/middleware.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,48 @@
from distutils.version import StrictVersion

from django.contrib import messages

try:
from django.utils.version import get_version
except ImportError:
from django import VERSION as DJANGO_VERSION

def get_version():
return ".".join(str(n) for n in DJANGO_VERSION[:3])

from async_messages import get_messages

if StrictVersion(get_version()) >= StrictVersion("1.10.0"):
from django.utils.deprecation import MiddlewareMixin as _MiddlewareBase

def _is_user_authenticated(user):
return bool(user.is_authenticated)
else:
_MiddlewareBase = object

def _is_user_authenticated(user):
return user.is_authenticated()


class AsyncMiddleware(_MiddlewareBase):
# In Django>=1.10 User.is_authenticated is a property, not a method but a
# strange one : CallbableBool.
# - If default User is used you can use it as a boolean either a method.
# - If this property is overrided you may have a bool instead and an
# exception.

class AsyncMiddleware(object):
def is_authenticated(self, request):
if hasattr(request, "session") and hasattr(request, "user"):
return _is_user_authenticated(request.user)
else:
return False

def process_response(self, request, response):
"""
Check for messages for this user and, if it exists,
call the messages API with it
"""
if hasattr(request, "session") and hasattr(request, "user") and request.user.is_authenticated():
if self.is_authenticated(request):
msgs = get_messages(request.user)
if msgs:
for msg, level in msgs:
Expand Down
10 changes: 10 additions & 0 deletions manage.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/usr/bin/env python
import os
import sys

if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "tests.settings")

from django.core.management import execute_from_command_line

execute_from_command_line(sys.argv)
7 changes: 3 additions & 4 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
Django==1.4
django-nose==1.1
nose==1.1.2
pinocchio==0.3.1
django-nose>=1.1
nose>=1.1.2
pinocchio>=0.3.1
45 changes: 0 additions & 45 deletions runtests.py

This file was deleted.

2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from setuptools import setup, find_packages

setup(name='django-async-messages',
version='0.3.1',
version='0.3.2',
url='https://github.com/codeinthehole/django-async-messages',
author="David Winterbottom",
author_email="[email protected]",
Expand Down
73 changes: 73 additions & 0 deletions tests/settings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import django
from os import path

DEBUG = False

ROOT_URLCONF = 'tests.urls'

DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
}
}

INSTALLED_APPS = [
'django.contrib.auth',
'django.contrib.admin',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'async_messages',
'tests'
]


if django.VERSION >= (1, 10):
MIDDLEWARE = (
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'async_messages.middleware.AsyncMiddleware'
)
else:
MIDDLEWARE_CLASSES = (
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'async_messages.middleware.AsyncMiddleware'
)

SITE_ID = 1

if django.VERSION >= (1, 8):
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [
path.join(path.dirname(__file__), "templates"),
],
'OPTIONS': {
'context_processors': [
# Insert your TEMPLATE_CONTEXT_PROCESSORS here or use this
# list if you haven't customized them:
'django.contrib.auth.context_processors.auth',
'django.template.context_processors.debug',
'django.template.context_processors.i18n',
'django.template.context_processors.media',
'django.template.context_processors.static',
'django.template.context_processors.tz',
'django.contrib.messages.context_processors.messages',
],
},
},
]
else:
TEMPLATE_DIRS = (
path.join(path.dirname(__file__), "templates"),
)

SECRET_KEY = 'foobarbaz'
19 changes: 16 additions & 3 deletions tests/tests.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
from django.contrib import auth
from django.contrib.auth.models import User
from django.contrib.messages import constants
from django.test import TestCase
from django.test.client import Client
from django.contrib.auth.models import User
from django.contrib.messages import constants, set_level

from async_messages import message_user, message_users, messages
from async_messages import (
message_user, message_users, messages, AsyncMessageException,
)


class MiddlewareTests(TestCase):
Expand Down Expand Up @@ -44,6 +47,16 @@ def test_anonymous(self):
msgs = list(response.context['messages'])
self.assertEqual(0, len((msgs)))

def test_anonymous_message(self):
client = Client()
user = auth.get_user(client)

with self.assertRaises(AsyncMessageException) as e:
message_user(user, "Second Message")

self.assertEqual(str(e.exception),
'Anonymous users cannot send messages.')


class TestMessagesApi(TestCase):
def setUp(self):
Expand Down
18 changes: 14 additions & 4 deletions tests/urls.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
from django.conf.urls.defaults import patterns, url
import django
from django.conf.urls import url

urlpatterns = patterns('',
url(r'^$', 'tests.views.index'),
)
if django.VERSION >= (1, 8):
from . import views

urlpatterns = [
url(r'^$', views.index, name='views_test'),
]
else:
from django.conf.urls import patterns

urlpatterns = patterns('',
url(r'^$', 'tests.views.index', name='views_test'),
)
8 changes: 3 additions & 5 deletions tests/views.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
from django.template.response import TemplateResponse
from django.template import Template

from django.template import Template, RequestContext
from django.http import HttpResponse

def index(request):
t = Template("")
return TemplateResponse(request, t, {'a': 1000})
return HttpResponse(Template("").render(RequestContext(request, {'a': 1000})))
20 changes: 20 additions & 0 deletions tox.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
[tox]
envlist = py27-dj{14,18,19,110,111},py36-dj{18,19,110,111,20}

[testenv]
deps =
-r{toxinidir}/requirements.txt
dj14: Django>=1.4,<1.5
dj18: Django>=1.8,<1.9
dj19: Django>=1.9,<1.10
dj110: Django>=1.10,<1.11
dj111: Django>=1.11,<2.0
dj20: Django>=2.0,<2.1
commands =
pip install -e .
python -Wd manage.py test tests
passenv =
PYTHONPATH
usedevelop = True
whitelist_externals=
pip