Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge branch 'master' of git://github.com/django/django into ticket_1…

…8780
  • Loading branch information...
commit 99bb6986674ce76b20ca70a18ba7cd1009a85413 2 parents 9e190e1 + 335a9f9
@nmartini authored
View
10 django/contrib/localflavor/hr/forms.py
@@ -4,6 +4,7 @@
"""
from __future__ import absolute_import, unicode_literals
+import datetime
import re
from django.contrib.localflavor.hr.hr_choices import (
@@ -91,17 +92,16 @@ def clean(self, value):
dd = int(matches.group('dd'))
mm = int(matches.group('mm'))
yyy = int(matches.group('yyy'))
- import datetime
try:
- datetime.date(yyy,mm,dd)
- except:
+ datetime.date(yyy, mm, dd)
+ except ValueError:
raise ValidationError(self.error_messages['date'])
# Validate checksum.
k = matches.group('k')
checksum = 0
- for i,j in zip(range(7,1,-1),range(6)):
- checksum+=i*(int(value[j])+int(value[13-i]))
+ for i, j in zip(range(7, 1, -1), range(6)):
+ checksum += i * (int(value[j]) + int(value[13 - i]))
m = 11 - checksum % 11
if m == 10:
raise ValidationError(self.error_messages['invalid'])
View
22 django/contrib/localflavor/ro/forms.py
@@ -4,6 +4,8 @@
"""
from __future__ import absolute_import, unicode_literals
+import datetime
+
from django.contrib.localflavor.ro.ro_counties import COUNTIES_CHOICES
from django.core.validators import EMPTY_VALUES
from django.forms import ValidationError, Field, RegexField, Select
@@ -69,10 +71,9 @@ def clean(self, value):
if value in EMPTY_VALUES:
return ''
# check birthdate digits
- import datetime
try:
- datetime.date(int(value[1:3]),int(value[3:5]),int(value[5:7]))
- except:
+ datetime.date(int(value[1:3]), int(value[3:5]), int(value[5:7]))
+ except ValueError:
raise ValidationError(self.error_messages['invalid'])
# checksum
key = '279146358279'
@@ -118,7 +119,7 @@ def clean(self, value):
# search for county name
normalized_CC = []
for entry in COUNTIES_CHOICES:
- normalized_CC.append((entry[0],entry[1].upper()))
+ normalized_CC.append((entry[0], entry[1].upper()))
for entry in normalized_CC:
if entry[1] == value:
return entry[0]
@@ -153,8 +154,8 @@ def clean(self, value):
value = super(ROIBANField, self).clean(value)
if value in EMPTY_VALUES:
return ''
- value = value.replace('-','')
- value = value.replace(' ','')
+ value = value.replace('-', '')
+ value = value.replace(' ', '')
value = value.upper()
if value[0:2] != 'RO':
raise ValidationError(self.error_messages['invalid'])
@@ -185,10 +186,10 @@ def clean(self, value):
value = super(ROPhoneNumberField, self).clean(value)
if value in EMPTY_VALUES:
return ''
- value = value.replace('-','')
- value = value.replace('(','')
- value = value.replace(')','')
- value = value.replace(' ','')
+ value = value.replace('-', '')
+ value = value.replace('(', '')
+ value = value.replace(')', '')
+ value = value.replace(' ', '')
if len(value) != 10:
raise ValidationError(self.error_messages['invalid'])
return value
@@ -202,4 +203,3 @@ class ROPostalCodeField(RegexField):
def __init__(self, max_length=6, min_length=6, *args, **kwargs):
super(ROPostalCodeField, self).__init__(r'^[0-9][0-8][0-9]{4}$',
max_length, min_length, *args, **kwargs)
-
View
2  django/core/cache/backends/memcached.py
@@ -141,7 +141,7 @@ def __init__(self, server, params):
)
try:
import memcache
- except:
+ except ImportError:
raise InvalidCacheBackendError(
"Memcached cache backend requires either the 'memcache' or 'cmemcache' library"
)
View
2  django/core/mail/backends/console.py
@@ -21,7 +21,7 @@ def send_messages(self, email_messages):
stream_created = self.open()
for message in email_messages:
self.stream.write('%s\n' % message.message().as_string())
- self.stream.write('-'*79)
+ self.stream.write('-' * 79)
self.stream.write('\n')
self.stream.flush() # flush after each message
if stream_created:
View
6 django/db/backends/creation.py
@@ -1,3 +1,4 @@
+import hashlib
import sys
import time
@@ -27,7 +28,10 @@ def _digest(self, *args):
Generates a 32-bit digest of a set of arguments that can be used to
shorten identifying names.
"""
- return '%x' % (abs(hash(args)) % 4294967296) # 2**32
+ h = hashlib.md5()
+ for arg in args:
+ h.update(arg)
+ return h.hexdigest()[:8]
def sql_create_model(self, model, style, known_models=set()):
"""
View
5 django/db/backends/sqlite3/base.py
@@ -412,7 +412,4 @@ def _sqlite_format_dtdelta(dt, conn, days, secs, usecs):
return str(dt)
def _sqlite_regexp(re_pattern, re_string):
- try:
- return bool(re.search(re_pattern, re_string))
- except:
- return False
+ return bool(re.search(re_pattern, re_string))
View
8 django/forms/widgets.py
@@ -507,11 +507,7 @@ def __init__(self, attrs=None, check_test=None):
def render(self, name, value, attrs=None):
final_attrs = self.build_attrs(attrs, type='checkbox', name=name)
- try:
- result = self.check_test(value)
- except: # Silently catch exceptions
- result = False
- if result:
+ if self.check_test(value):
final_attrs['checked'] = 'checked'
if not (value is True or value is False or value is None or value == ''):
# Only add the 'value' attribute if a value is non-empty.
@@ -525,7 +521,7 @@ def value_from_datadict(self, data, files, name):
return False
value = data.get(name)
# Translate true and false strings to boolean values.
- values = {'true': True, 'false': False}
+ values = {'true': True, 'false': False}
if isinstance(value, six.string_types):
value = values.get(value.lower(), value)
return value
View
5 django/http/multipartparser.py
@@ -68,11 +68,10 @@ def __init__(self, META, input_data, upload_handlers, encoding=None):
if not boundary or not cgi.valid_boundary(boundary):
raise MultiPartParserError('Invalid boundary in multipart: %s' % boundary)
-
# Content-Length should contain the length of the body we are about
# to receive.
try:
- content_length = int(META.get('HTTP_CONTENT_LENGTH', META.get('CONTENT_LENGTH',0)))
+ content_length = int(META.get('HTTP_CONTENT_LENGTH', META.get('CONTENT_LENGTH', 0)))
except (ValueError, TypeError):
content_length = 0
@@ -178,7 +177,7 @@ def parse(self):
content_type = meta_data.get('content-type', ('',))[0].strip()
try:
- charset = meta_data.get('content-type', (0,{}))[1].get('charset', None)
+ charset = meta_data.get('content-type', (0, {}))[1].get('charset', None)
except:
charset = None
View
26 docs/ref/contrib/gis/install.txt
@@ -80,7 +80,7 @@ geospatial libraries:
Program Description Required Supported Versions
======================== ==================================== ================================ ==========================
:ref:`GEOS <ref-geos>` Geometry Engine Open Source Yes 3.3, 3.2, 3.1, 3.0
-`PROJ.4`_ Cartographic Projections library Yes (PostgreSQL and SQLite only) 4.7, 4.6, 4.5, 4.4
+`PROJ.4`_ Cartographic Projections library Yes (PostgreSQL and SQLite only) 4.8, 4.7, 4.6, 4.5, 4.4
:ref:`GDAL <ref-gdal>` Geospatial Data Abstraction Library No (but, required for SQLite) 1.9, 1.8, 1.7, 1.6, 1.5
:ref:`GeoIP <ref-geoip>` IP-based geolocation library No 1.4
`PostGIS`__ Spatial extensions for PostgreSQL Yes (PostgreSQL only) 1.5, 1.4, 1.3
@@ -140,16 +140,16 @@ internal geometry representation used by GeoDjango (it's behind the "lazy"
geometries). Specifically, the C API library is called (e.g., ``libgeos_c.so``)
directly from Python using ctypes.
-First, download GEOS 3.3.0 from the refractions Web site and untar the source
+First, download GEOS 3.3.5 from the refractions Web site and untar the source
archive::
- $ wget http://download.osgeo.org/geos/geos-3.3.0.tar.bz2
- $ tar xjf geos-3.3.0.tar.bz2
+ $ wget http://download.osgeo.org/geos/geos-3.3.5.tar.bz2
+ $ tar xjf geos-3.3.5.tar.bz2
Next, change into the directory where GEOS was unpacked, run the configure
script, compile, and install::
- $ cd geos-3.3.0
+ $ cd geos-3.3.5
$ ./configure
$ make
$ sudo make install
@@ -203,15 +203,15 @@ reference systems.
First, download the PROJ.4 source code and datum shifting files [#]_::
- $ wget http://download.osgeo.org/proj/proj-4.7.0.tar.gz
- $ wget http://download.osgeo.org/proj/proj-datumgrid-1.5.zip
+ $ wget http://download.osgeo.org/proj/proj-4.8.0.tar.gz
+ $ wget http://download.osgeo.org/proj/proj-datumgrid-1.5.tar.gz
Next, untar the source code archive, and extract the datum shifting files in the
``nad`` subdirectory. This must be done *prior* to configuration::
- $ tar xzf proj-4.7.0.tar.gz
- $ cd proj-4.7.0/nad
- $ unzip ../../proj-datumgrid-1.5.zip
+ $ tar xzf proj-4.8.0.tar.gz
+ $ cd proj-4.8.0/nad
+ $ tar xzf ../../proj-datumgrid-1.5.tar.gz
$ cd ..
Finally, configure, make and install PROJ.4::
@@ -239,9 +239,9 @@ installed prior to building PostGIS.
First download the source archive, and extract::
- $ wget http://postgis.refractions.net/download/postgis-1.5.2.tar.gz
- $ tar xzf postgis-1.5.2.tar.gz
- $ cd postgis-1.5.2
+ $ wget http://postgis.refractions.net/download/postgis-1.5.5.tar.gz
+ $ tar xzf postgis-1.5.5.tar.gz
+ $ cd postgis-1.5.5
Next, configure, make and install PostGIS::
View
5 docs/ref/forms/validation.txt
@@ -70,9 +70,8 @@ overridden:
formfield-specific piece of validation and, possibly,
cleaning/normalizing the data.
- Just like the general field ``clean()`` method, above, this method
- should return the cleaned data, regardless of whether it changed
- anything or not.
+ This method should return the cleaned value obtained from cleaned_data,
+ regardless of whether it changed anything or not.
* The Form subclass's ``clean()`` method. This method can perform
any validation that requires access to multiple fields from the form at
View
4 docs/ref/forms/widgets.txt
@@ -310,6 +310,10 @@ commonly used groups of widgets:
A callable that takes the value of the CheckBoxInput and returns
``True`` if the checkbox should be checked for that value.
+ .. versionchanged:: 1.5
+ Exceptions from ``check_test`` used to be silenced by its caller,
+ this is no longer the case, they will propagate upwards.
+
``Select``
~~~~~~~~~~
View
32 docs/topics/security.txt
@@ -76,9 +76,17 @@ POST to your Web site and have another logged in user unwittingly submit that
form. The malicious user would have to know the nonce, which is user specific
(using a cookie).
+When deployed with :ref:`HTTPS <security-recommendation-ssl>`,
+``CsrfViewMiddleware`` will check that the HTTP referer header is set to a
+URL on the same origin (including subdomain and port). Because HTTPS
+provides additional security, it is imperative to ensure connections use HTTPS
+where it is available by forwarding insecure connection requests and using
+HSTS for supported browsers.
+
Be very careful with marking views with the ``csrf_exempt`` decorator unless
it is absolutely necessary.
+
SQL injection protection
========================
@@ -112,6 +120,8 @@ The middleware is strongly recommended for any site that does not need to have
its pages wrapped in a frame by third party sites, or only needs to allow that
for a small section of the site.
+.. _security-recommendation-ssl:
+
SSL/HTTPS
=========
@@ -147,7 +157,15 @@ server, there are some additional steps you may need:
any POST data being accepted over HTTP (which will be fine if you are
redirecting all HTTP traffic to HTTPS).
-.. _additional-security-topics:
+* Use HTTP Strict Transport Security (HSTS)
+
+ HSTS is an HTTP header that informs a browser that all future connections
+ to a particular site should always use HTTPS. Combined with redirecting
+ requests over HTTP to HTTPS, this will ensure that connections always enjoy
+ the added security of SSL provided one successful connection has occurred.
+ HSTS is usually configured on the web server.
+
+.. _host-headers-virtual-hosting:
Host headers and virtual hosting
================================
@@ -158,15 +176,17 @@ Site Scripting attacks, they can be used for Cross-Site Request
Forgery and cache poisoning attacks in some circumstances. We
recommend you ensure your Web server is configured such that:
- * It always validates incoming HTTP ``Host`` headers against the expected
- host name.
- * Disallows requests with no ``Host`` header.
- * Is *not* configured with a catch-all virtual host that forwards requests
- to a Django application.
+* It always validates incoming HTTP ``Host`` headers against the expected
+ host name.
+* Disallows requests with no ``Host`` header.
+* Is *not* configured with a catch-all virtual host that forwards requests
+ to a Django application.
Additionally, as of 1.3.1, Django requires you to explicitly enable support for
the ``X-Forwarded-Host`` header if your configuration requires it.
+.. _additional-security-topics:
+
Additional security topics
==========================
View
2  tests/regressiontests/file_uploads/tests.py
@@ -100,7 +100,7 @@ def test_unicode_file_name(self):
try:
os.unlink(file1.name)
- except:
+ except OSError:
pass
self.assertEqual(response.status_code, 200)
View
27 tests/regressiontests/fixtures_regress/tests.py
@@ -21,18 +21,15 @@
ExternalDependency, Thingy)
-pre_save_checks = []
-def animal_pre_save_check(signal, sender, instance, **kwargs):
- "A signal that is used to check the type of data loaded from fixtures"
- pre_save_checks.append(
- (
- 'Count = %s (%s)' % (instance.count, type(instance.count)),
- 'Weight = %s (%s)' % (instance.weight, type(instance.weight)),
+class TestFixtures(TestCase):
+ def animal_pre_save_check(self, signal, sender, instance, **kwargs):
+ self.pre_save_checks.append(
+ (
+ 'Count = %s (%s)' % (instance.count, type(instance.count)),
+ 'Weight = %s (%s)' % (instance.weight, type(instance.weight)),
+ )
)
- )
-
-class TestFixtures(TestCase):
def test_duplicate_pk(self):
"""
This is a regression test for ticket #3790.
@@ -111,7 +108,6 @@ def test_absolute_path(self):
)
self.assertEqual(Absolute.load_count, 1)
-
def test_unknown_format(self):
"""
Test for ticket #4371 -- Loading data of an unknown format should fail
@@ -246,9 +242,8 @@ def test_field_value_coerce(self):
Test for tickets #8298, #9942 - Field values should be coerced into the
correct type by the deserializer, not as part of the database write.
"""
- global pre_save_checks
- pre_save_checks = []
- signals.pre_save.connect(animal_pre_save_check)
+ self.pre_save_checks = []
+ signals.pre_save.connect(self.animal_pre_save_check)
try:
management.call_command(
'loaddata',
@@ -257,14 +252,14 @@ def test_field_value_coerce(self):
commit=False,
)
self.assertEqual(
- pre_save_checks,
+ self.pre_save_checks,
[
("Count = 42 (<%s 'int'>)" % ('class' if PY3 else 'type'),
"Weight = 1.2 (<%s 'float'>)" % ('class' if PY3 else 'type'))
]
)
finally:
- signals.pre_save.disconnect(animal_pre_save_check)
+ signals.pre_save.disconnect(self.animal_pre_save_check)
def test_dumpdata_uses_default_manager(self):
"""
View
10 tests/regressiontests/forms/tests/widgets.py
@@ -216,13 +216,9 @@ def test_checkboxinput(self):
self.assertHTMLEqual(w.render('greeting', 'hello there'), '<input checked="checked" type="checkbox" name="greeting" value="hello there" />')
self.assertHTMLEqual(w.render('greeting', 'hello & goodbye'), '<input checked="checked" type="checkbox" name="greeting" value="hello &amp; goodbye" />')
- # A subtlety: If the 'check_test' argument cannot handle a value and raises any
- # exception during its __call__, then the exception will be swallowed and the box
- # will not be checked. In this example, the 'check_test' assumes the value has a
- # startswith() method, which fails for the values True, False and None.
- self.assertHTMLEqual(w.render('greeting', True), '<input type="checkbox" name="greeting" />')
- self.assertHTMLEqual(w.render('greeting', False), '<input type="checkbox" name="greeting" />')
- self.assertHTMLEqual(w.render('greeting', None), '<input type="checkbox" name="greeting" />')
+ # Ticket #17888: calling check_test shouldn't swallow exceptions
+ with self.assertRaises(AttributeError):
+ w.render('greeting', True)
# The CheckboxInput widget will return False if the key is not found in the data
# dictionary (because HTML form submission doesn't send any result for unchecked
View
4 tests/regressiontests/handlers/tests.py
@@ -17,10 +17,8 @@ def test_lock_safety(self):
# Try running the handler, it will fail in load_middleware
handler = WSGIHandler()
self.assertEqual(handler.initLock.locked(), False)
- try:
+ with self.assertRaises(Exception):
handler(None, None)
- except:
- pass
self.assertEqual(handler.initLock.locked(), False)
# Reset settings
settings.MIDDLEWARE_CLASSES = old_middleware_classes
View
7 tests/regressiontests/i18n/commands/compilation.py
@@ -3,11 +3,12 @@
from django.core.management import call_command, CommandError
from django.test import TestCase
from django.test.utils import override_settings
-from django.utils import translation
+from django.utils import translation, six
from django.utils.six import StringIO
test_dir = os.path.abspath(os.path.dirname(__file__))
+
class MessageCompilationTests(TestCase):
def setUp(self):
@@ -19,8 +20,8 @@ def tearDown(self):
class PoFileTests(MessageCompilationTests):
- LOCALE='es_AR'
- MO_FILE='locale/%s/LC_MESSAGES/django.mo' % LOCALE
+ LOCALE = 'es_AR'
+ MO_FILE = 'locale/%s/LC_MESSAGES/django.mo' % LOCALE
def test_bom_rejection(self):
os.chdir(test_dir)
View
5 tests/regressiontests/queries/tests.py
@@ -1677,10 +1677,7 @@ def test_evaluated_queryset_as_argument(self):
list(n_list)
# Use the note queryset in a query, and evalute
# that query in a way that involves cloning.
- try:
- self.assertEqual(ExtraInfo.objects.filter(note__in=n_list)[0].info, 'good')
- except:
- self.fail('Query should be clonable')
+ self.assertEqual(ExtraInfo.objects.filter(note__in=n_list)[0].info, 'good')
class EmptyQuerySetTests(TestCase):
View
22 tests/regressiontests/settings_tests/tests.py
@@ -71,16 +71,18 @@ class SettingGetter(object):
def __init__(self):
self.test = getattr(settings, 'TEST', 'undefined')
-testvalue = None
-def signal_callback(sender, setting, value, **kwargs):
- if setting == 'TEST':
- global testvalue
- testvalue = value
+class SettingsTests(TestCase):
+ def setUp(self):
+ self.testvalue = None
+ signals.setting_changed.connect(self.signal_callback)
-signals.setting_changed.connect(signal_callback)
+ def tearDown(self):
+ signals.setting_changed.disconnect(self.signal_callback)
-class SettingsTests(TestCase):
+ def signal_callback(self, sender, setting, value, **kwargs):
+ if setting == 'TEST':
+ self.testvalue = value
def test_override(self):
settings.TEST = 'test'
@@ -128,12 +130,12 @@ def test_class_decorator(self):
def test_signal_callback_context_manager(self):
self.assertRaises(AttributeError, getattr, settings, 'TEST')
with self.settings(TEST='override'):
- self.assertEqual(testvalue, 'override')
- self.assertEqual(testvalue, None)
+ self.assertEqual(self.testvalue, 'override')
+ self.assertEqual(self.testvalue, None)
@override_settings(TEST='override')
def test_signal_callback_decorator(self):
- self.assertEqual(testvalue, 'override')
+ self.assertEqual(self.testvalue, 'override')
#
# Regression tests for #10130: deleting settings.
View
70 tests/regressiontests/signals_regress/tests.py
@@ -6,31 +6,6 @@
from .models import Author, Book
-signal_output = []
-
-def pre_save_test(signal, sender, instance, **kwargs):
- signal_output.append('pre_save signal, %s' % instance)
- if kwargs.get('raw'):
- signal_output.append('Is raw')
-
-def post_save_test(signal, sender, instance, **kwargs):
- signal_output.append('post_save signal, %s' % instance)
- if 'created' in kwargs:
- if kwargs['created']:
- signal_output.append('Is created')
- else:
- signal_output.append('Is updated')
- if kwargs.get('raw'):
- signal_output.append('Is raw')
-
-def pre_delete_test(signal, sender, instance, **kwargs):
- signal_output.append('pre_save signal, %s' % instance)
- signal_output.append('instance.id is not None: %s' % (instance.id != None))
-
-def post_delete_test(signal, sender, instance, **kwargs):
- signal_output.append('post_delete signal, %s' % instance)
- signal_output.append('instance.id is not None: %s' % (instance.id != None))
-
class SignalsRegressTests(TestCase):
"""
Testing signals before/after saving and deleting.
@@ -38,12 +13,35 @@ class SignalsRegressTests(TestCase):
def get_signal_output(self, fn, *args, **kwargs):
# Flush any existing signal output
- global signal_output
- signal_output = []
+ self.signal_output = []
fn(*args, **kwargs)
- return signal_output
+ return self.signal_output
+
+ def pre_save_test(self, signal, sender, instance, **kwargs):
+ self.signal_output.append('pre_save signal, %s' % instance)
+ if kwargs.get('raw'):
+ self.signal_output.append('Is raw')
+
+ def post_save_test(self, signal, sender, instance, **kwargs):
+ self.signal_output.append('post_save signal, %s' % instance)
+ if 'created' in kwargs:
+ if kwargs['created']:
+ self.signal_output.append('Is created')
+ else:
+ self.signal_output.append('Is updated')
+ if kwargs.get('raw'):
+ self.signal_output.append('Is raw')
+
+ def pre_delete_test(self, signal, sender, instance, **kwargs):
+ self.signal_output.append('pre_save signal, %s' % instance)
+ self.signal_output.append('instance.id is not None: %s' % (instance.id != None))
+
+ def post_delete_test(self, signal, sender, instance, **kwargs):
+ self.signal_output.append('post_delete signal, %s' % instance)
+ self.signal_output.append('instance.id is not None: %s' % (instance.id != None))
def setUp(self):
+ self.signal_output = []
# Save up the number of connected signals so that we can check at the end
# that all the signals we register get properly unregistered (#9989)
self.pre_signals = (len(models.signals.pre_save.receivers),
@@ -51,16 +49,16 @@ def setUp(self):
len(models.signals.pre_delete.receivers),
len(models.signals.post_delete.receivers))
- models.signals.pre_save.connect(pre_save_test)
- models.signals.post_save.connect(post_save_test)
- models.signals.pre_delete.connect(pre_delete_test)
- models.signals.post_delete.connect(post_delete_test)
+ models.signals.pre_save.connect(self.pre_save_test)
+ models.signals.post_save.connect(self.post_save_test)
+ models.signals.pre_delete.connect(self.pre_delete_test)
+ models.signals.post_delete.connect(self.post_delete_test)
def tearDown(self):
- models.signals.post_delete.disconnect(post_delete_test)
- models.signals.pre_delete.disconnect(pre_delete_test)
- models.signals.post_save.disconnect(post_save_test)
- models.signals.pre_save.disconnect(pre_save_test)
+ models.signals.post_delete.disconnect(self.post_delete_test)
+ models.signals.pre_delete.disconnect(self.pre_delete_test)
+ models.signals.post_save.disconnect(self.post_save_test)
+ models.signals.pre_save.disconnect(self.pre_save_test)
# Check that all our signals got disconnected properly.
post_signals = (len(models.signals.pre_save.receivers),
View
22 tests/regressiontests/transactions_regress/tests.py
@@ -1,7 +1,6 @@
from __future__ import absolute_import
-from django.core.exceptions import ImproperlyConfigured
-from django.db import connection, connections, transaction, DEFAULT_DB_ALIAS
+from django.db import connection, connections, transaction, DEFAULT_DB_ALIAS, DatabaseError
from django.db.transaction import commit_on_success, commit_manually, TransactionManagementError
from django.test import TransactionTestCase, skipUnlessDBFeature
from django.test.utils import override_settings
@@ -151,21 +150,14 @@ def create_system_user():
# Create a user
create_system_user()
- try:
- # The second call to create_system_user should fail for violating a unique constraint
- # (it's trying to re-create the same user)
+ with self.assertRaises(DatabaseError):
+ # The second call to create_system_user should fail for violating
+ # a unique constraint (it's trying to re-create the same user)
create_system_user()
- except:
- pass
- else:
- raise ImproperlyConfigured('Unique constraint not enforced on django.contrib.auth.models.User')
- try:
- # Try to read the database. If the last transaction was indeed closed,
- # this should cause no problems
- _ = User.objects.all()[0]
- except:
- self.fail("A transaction consisting of a failed operation was not closed.")
+ # Try to read the database. If the last transaction was indeed closed,
+ # this should cause no problems
+ User.objects.all()[0]
@override_settings(DEBUG=True)
def test_failing_query_transaction_closed_debug(self):
Please sign in to comment.
Something went wrong with that request. Please try again.