summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AUTHORS1
-rw-r--r--django/core/management/commands/loaddata.py20
-rw-r--r--django/db/backends/postgresql/operations.py5
-rw-r--r--django/db/models/fields/__init__.py6
-rw-r--r--django/utils/datastructures.py4
-rw-r--r--setup.py11
-rw-r--r--tests/regressiontests/datastructures/tests.py6
-rw-r--r--tests/regressiontests/datatypes/models.py26
-rw-r--r--tests/regressiontests/fixtures_regress/fixtures/absolute.json9
-rw-r--r--tests/regressiontests/fixtures_regress/models.py22
-rw-r--r--tests/regressiontests/string_lookup/models.py8
11 files changed, 103 insertions, 15 deletions
diff --git a/AUTHORS b/AUTHORS
index 47a0646567..9c28d73730 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -71,6 +71,7 @@ answer newbie questions, and generally made Django that much better:
boobsd@gmail.com
Andrew Brehaut <http://brehaut.net/blog>
brut.alll@gmail.com
+ btoll@bestweb.net
Jonathan Buchanan <jonathan.buchanan@gmail.com>
Can Burak Çilingir <canburak@cs.bilgi.edu.tr>
Trevor Caira <trevor@caira.com>
diff --git a/django/core/management/commands/loaddata.py b/django/core/management/commands/loaddata.py
index e95be6b8d7..dde9e6eb80 100644
--- a/django/core/management/commands/loaddata.py
+++ b/django/core/management/commands/loaddata.py
@@ -30,7 +30,8 @@ class Command(BaseCommand):
show_traceback = options.get('traceback', False)
# Keep a count of the installed objects and fixtures
- count = [0, 0]
+ fixture_count = 0
+ object_count = 0
models = set()
humanize = lambda dirname: dirname and "'%s'" % dirname or 'absolute path'
@@ -65,7 +66,12 @@ class Command(BaseCommand):
else:
print "Skipping fixture '%s': %s is not a known serialization format" % (fixture_name, format)
- for fixture_dir in app_fixtures + list(settings.FIXTURE_DIRS) + ['']:
+ if os.path.isabs(fixture_name):
+ fixture_dirs = [fixture_name]
+ else:
+ fixture_dirs = app_fixtures + list(settings.FIXTURE_DIRS) + ['']
+
+ for fixture_dir in fixture_dirs:
if verbosity > 1:
print "Checking %s for fixtures..." % humanize(fixture_dir)
@@ -86,14 +92,14 @@ class Command(BaseCommand):
transaction.leave_transaction_management()
return
else:
- count[1] += 1
+ fixture_count += 1
if verbosity > 0:
print "Installing %s fixture '%s' from %s." % \
(format, fixture_name, humanize(fixture_dir))
try:
objects = serializers.deserialize(format, fixture)
for obj in objects:
- count[0] += 1
+ object_count += 1
models.add(obj.object.__class__)
obj.save()
label_found = True
@@ -113,7 +119,7 @@ class Command(BaseCommand):
print "No %s fixture '%s' in %s." % \
(format, fixture_name, humanize(fixture_dir))
- if count[0] > 0:
+ if object_count > 0:
sequence_sql = connection.ops.sequence_reset_sql(self.style, models)
if sequence_sql:
if verbosity > 1:
@@ -124,9 +130,9 @@ class Command(BaseCommand):
transaction.commit()
transaction.leave_transaction_management()
- if count[0] == 0:
+ if object_count == 0:
if verbosity >= 2:
print "No fixtures found."
else:
if verbosity > 0:
- print "Installed %d object(s) from %d fixture(s)" % tuple(count)
+ print "Installed %d object(s) from %d fixture(s)" % (object_count, fixture_count)
diff --git a/django/db/backends/postgresql/operations.py b/django/db/backends/postgresql/operations.py
index d2c65a8753..ec54e165fb 100644
--- a/django/db/backends/postgresql/operations.py
+++ b/django/db/backends/postgresql/operations.py
@@ -27,6 +27,11 @@ class DatabaseOperations(BaseDatabaseOperations):
def deferrable_sql(self):
return " DEFERRABLE INITIALLY DEFERRED"
+ def field_cast_sql(self, db_type):
+ if db_type == 'inet':
+ return 'CAST(%s AS TEXT)'
+ return '%s'
+
def last_insert_id(self, cursor, table_name, pk_name):
cursor.execute("SELECT CURRVAL('\"%s_%s_seq\"')" % (table_name, pk_name))
return cursor.fetchone()[0]
diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py
index 8c35d63e0f..a295edfd79 100644
--- a/django/db/models/fields/__init__.py
+++ b/django/db/models/fields/__init__.py
@@ -243,7 +243,11 @@ class Field(object):
value = int(value)
except ValueError:
raise ValueError("The __year lookup type requires an integer argument")
- return ['%s-01-01 00:00:00' % value, '%s-12-31 23:59:59.999999' % value]
+ if settings.DATABASE_ENGINE == 'sqlite3':
+ first = '%s-01-01'
+ else:
+ first = '%s-01-01 00:00:00'
+ return [first % value, '%s-12-31 23:59:59.999999' % value]
raise TypeError("Field has invalid lookup: %s" % lookup_type)
def has_default(self):
diff --git a/django/utils/datastructures.py b/django/utils/datastructures.py
index a2b78a31c5..4c278c0d8e 100644
--- a/django/utils/datastructures.py
+++ b/django/utils/datastructures.py
@@ -155,6 +155,10 @@ class SortedDict(dict):
"""
return '{%s}' % ', '.join(['%r: %r' % (k, v) for k, v in self.items()])
+ def clear(self):
+ super(SortedDict, self).clear()
+ self.keyOrder = []
+
class MultiValueDictKeyError(KeyError):
pass
diff --git a/setup.py b/setup.py
index 61e0fd55e9..3cbfc55460 100644
--- a/setup.py
+++ b/setup.py
@@ -27,19 +27,16 @@ for scheme in INSTALL_SCHEMES.values():
# an easy way to do this.
packages, data_files = [], []
root_dir = os.path.dirname(__file__)
-django_dir = os.path.join(root_dir, 'django')
-pieces = fullsplit(root_dir)
-if pieces[-1] == '':
- len_root_dir = len(pieces) - 1
-else:
- len_root_dir = len(pieces)
+if root_dir != '':
+ os.chdir(root_dir)
+django_dir = 'django'
for dirpath, dirnames, filenames in os.walk(django_dir):
# Ignore dirnames that start with '.'
for i, dirname in enumerate(dirnames):
if dirname.startswith('.'): del dirnames[i]
if '__init__.py' in filenames:
- packages.append('.'.join(fullsplit(dirpath)[len_root_dir:]))
+ packages.append('.'.join(fullsplit(dirpath)))
elif filenames:
data_files.append([dirpath, [os.path.join(dirpath, f) for f in filenames]])
diff --git a/tests/regressiontests/datastructures/tests.py b/tests/regressiontests/datastructures/tests.py
index 172057f080..b51b4b1233 100644
--- a/tests/regressiontests/datastructures/tests.py
+++ b/tests/regressiontests/datastructures/tests.py
@@ -101,6 +101,12 @@ Init from sequence of tuples
>>> print repr(d)
{1: 'one', 0: 'zero', 2: 'two'}
+>>> d.clear()
+>>> d
+{}
+>>> d.keyOrder
+[]
+
### DotExpandedDict ############################################################
>>> d = DotExpandedDict({'person.1.firstname': ['Simon'], 'person.1.lastname': ['Willison'], 'person.2.firstname': ['Adrian'], 'person.2.lastname': ['Holovaty']})
diff --git a/tests/regressiontests/datatypes/models.py b/tests/regressiontests/datatypes/models.py
index ff9666bc0c..9ebb6402e2 100644
--- a/tests/regressiontests/datatypes/models.py
+++ b/tests/regressiontests/datatypes/models.py
@@ -56,4 +56,30 @@ datetime.date(1938, 6, 4)
datetime.time(5, 30)
>>> d3.consumed_at
datetime.datetime(2007, 4, 20, 16, 19, 59)
+
+# Year boundary tests (ticket #3689)
+
+>>> d = Donut(name='Date Test 2007', baked_date=datetime.datetime(year=2007, month=12, day=31), consumed_at=datetime.datetime(year=2007, month=12, day=31, hour=23, minute=59, second=59))
+>>> d.save()
+>>> d1 = Donut(name='Date Test 2006', baked_date=datetime.datetime(year=2006, month=1, day=1), consumed_at=datetime.datetime(year=2006, month=1, day=1))
+>>> d1.save()
+
+>>> Donut.objects.filter(baked_date__year=2007)
+[<Donut: Date Test 2007>]
+
+>>> Donut.objects.filter(baked_date__year=2006)
+[<Donut: Date Test 2006>]
+
+>>> Donut.objects.filter(consumed_at__year=2007).order_by('name')
+[<Donut: Apple Fritter>, <Donut: Date Test 2007>]
+
+>>> Donut.objects.filter(consumed_at__year=2006)
+[<Donut: Date Test 2006>]
+
+>>> Donut.objects.filter(consumed_at__year=2005)
+[]
+
+>>> Donut.objects.filter(consumed_at__year=2008)
+[]
+
"""}
diff --git a/tests/regressiontests/fixtures_regress/fixtures/absolute.json b/tests/regressiontests/fixtures_regress/fixtures/absolute.json
new file mode 100644
index 0000000000..37ed3f6886
--- /dev/null
+++ b/tests/regressiontests/fixtures_regress/fixtures/absolute.json
@@ -0,0 +1,9 @@
+[
+ {
+ "pk": "1",
+ "model": "fixtures_regress.absolute",
+ "fields": {
+ "name": "Load Absolute Path Test"
+ }
+ }
+] \ No newline at end of file
diff --git a/tests/regressiontests/fixtures_regress/models.py b/tests/regressiontests/fixtures_regress/models.py
index a62925eb37..144debe05a 100644
--- a/tests/regressiontests/fixtures_regress/models.py
+++ b/tests/regressiontests/fixtures_regress/models.py
@@ -1,6 +1,7 @@
from django.db import models
from django.contrib.auth.models import User
from django.conf import settings
+import os
class Animal(models.Model):
name = models.CharField(max_length=150)
@@ -28,6 +29,16 @@ class Stuff(models.Model):
name = None
return unicode(name) + u' is owned by ' + unicode(self.owner)
+class Absolute(models.Model):
+ name = models.CharField(max_length=40)
+
+ load_count = 0
+
+ def __init__(self, *args, **kwargs):
+ super(Absolute, self).__init__(*args, **kwargs)
+ Absolute.load_count += 1
+
+
__test__ = {'API_TESTS':"""
>>> from django.core import management
@@ -49,4 +60,15 @@ __test__ = {'API_TESTS':"""
>>> Stuff.objects.all()
[<Stuff: None is owned by None>]
+###############################################
+# Regression test for ticket #6436 --
+# os.path.join will throw away the initial parts of a path if it encounters
+# an absolute path. This means that if a fixture is specified as an absolute path,
+# we need to make sure we don't discover the absolute path in every fixture directory.
+
+>>> load_absolute_path = os.path.join(os.path.dirname(__file__), 'fixtures', 'absolute.json')
+>>> management.call_command('loaddata', load_absolute_path, verbosity=0)
+>>> Absolute.load_count
+1
+
"""}
diff --git a/tests/regressiontests/string_lookup/models.py b/tests/regressiontests/string_lookup/models.py
index 9deeb18763..1bdb2d4452 100644
--- a/tests/regressiontests/string_lookup/models.py
+++ b/tests/regressiontests/string_lookup/models.py
@@ -39,6 +39,7 @@ class Base(models.Model):
class Article(models.Model):
name = models.CharField(max_length=50)
text = models.TextField()
+ submitted_from = models.IPAddressField(blank=True, null=True)
def __str__(self):
return "Article %s" % self.name
@@ -98,4 +99,11 @@ __test__ = {'API_TESTS': ur"""
>>> Article.objects.get(text__contains='quick brown fox')
<Article: Article Test>
+
+# Regression test for #708: "like" queries on IP address fields require casting
+# to text (on PostgreSQL).
+>>> Article(name='IP test', text='The body', submitted_from='192.0.2.100').save()
+>>> Article.objects.filter(submitted_from__contains='192.0.2')
+[<Article: Article IP test>]
+
"""}