Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

gis: Merged revisions 7499,7501-7502,7504,7509-7510 via svnmerge from…

… trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/gis@7511 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 5922dabea0e622af3f33d17566363a74ff533cd1 1 parent e5b52f9
Justin Bronn authored May 01, 2008
26  django/db/models/base.py
@@ -237,32 +237,6 @@ def __init__(self, *args, **kwargs):
237 237
                 raise TypeError, "'%s' is an invalid keyword argument for this function" % kwargs.keys()[0]
238 238
         dispatcher.send(signal=signals.post_init, sender=self.__class__, instance=self)
239 239
 
240  
-    def from_sequence(cls, values):
241  
-        """
242  
-        An alternate class constructor, primarily for internal use.
243  
-
244  
-        Creates a model instance from a sequence of values (which corresponds
245  
-        to all the non-many-to-many fields in creation order. If there are more
246  
-        fields than values, the remaining (final) fields are given their
247  
-        default values.
248  
-
249  
-        ForeignKey fields can only be initialised using id values, not
250  
-        instances, in this method.
251  
-        """
252  
-        dispatcher.send(signal=signals.pre_init, sender=cls, args=values,
253  
-                kwargs={})
254  
-        obj = Empty()
255  
-        obj.__class__ = cls
256  
-        field_iter = iter(obj._meta.fields)
257  
-        for val, field in izip(values, field_iter):
258  
-            setattr(obj, field.attname, val)
259  
-        for field in field_iter:
260  
-            setattr(obj, field.attname, field.get_default())
261  
-        dispatcher.send(signal=signals.post_init, sender=cls, instance=obj)
262  
-        return obj
263  
-
264  
-    from_sequence = classmethod(from_sequence)
265  
-
266 240
     def __repr__(self):
267 241
         return smart_str(u'<%s: %s>' % (self.__class__.__name__, unicode(self)))
268 242
 
17  django/db/models/query.py
@@ -28,6 +28,17 @@ def __init__(self, model=None, query=None):
28 28
     # PYTHON MAGIC METHODS #
29 29
     ########################
30 30
 
  31
+    def __getstate__(self):
  32
+        """
  33
+        Allows the Queryset to be pickled.
  34
+        """
  35
+        # Force the cache to be fully populated.
  36
+        len(self)
  37
+
  38
+        obj_dict = self.__dict__.copy()
  39
+        obj_dict['_iter'] = None
  40
+        return obj_dict
  41
+
31 42
     def __repr__(self):
32 43
         return repr(list(self))
33 44
 
@@ -37,7 +48,7 @@ def __len__(self):
37 48
         # whilst not messing up any existing iterators against the queryset.
38 49
         if self._result_cache is None:
39 50
             if self._iter:
40  
-                self._result_cache = list(self._iter())
  51
+                self._result_cache = list(self._iter)
41 52
             else:
42 53
                 self._result_cache = list(self.iterator())
43 54
         elif self._iter:
@@ -153,7 +164,7 @@ def iterator(self):
153 164
                 obj, _ = get_cached_row(self.model, row, index_start,
154 165
                         max_depth, requested=requested)
155 166
             else:
156  
-                obj = self.model.from_sequence(row[index_start:])
  167
+                obj = self.model(*row[index_start:])
157 168
             for i, k in enumerate(extra_select):
158 169
                 setattr(obj, k, row[i])
159 170
             yield obj
@@ -644,7 +655,7 @@ def get_cached_row(klass, row, index_start, max_depth=0, cur_depth=0,
644 655
 
645 656
     restricted = requested is not None
646 657
     index_end = index_start + len(klass._meta.fields)
647  
-    obj = klass.from_sequence(row[index_start:index_end])
  658
+    obj = klass(*row[index_start:index_end])
648 659
     for f in klass._meta.fields:
649 660
         if (not f.rel or (not restricted and f.null) or
650 661
                 (restricted and f.name not in requested) or f.rel.parent_link):
21  django/db/models/sql/query.py
@@ -99,6 +99,24 @@ def __deepcopy__(self, memo):
99 99
         memo[id(self)] = result
100 100
         return result
101 101
 
  102
+    def __getstate__(self):
  103
+        """
  104
+        Pickling support.
  105
+        """
  106
+        obj_dict = self.__dict__.copy()
  107
+        del obj_dict['connection']
  108
+        return obj_dict
  109
+
  110
+    def __setstate__(self, obj_dict):
  111
+        """
  112
+        Unpickling support.
  113
+        """
  114
+        self.__dict__.update(obj_dict)
  115
+        # XXX: Need a better solution for this when multi-db stuff is
  116
+        # supported. It's the only class-reference to the module-level
  117
+        # connection variable.
  118
+        self.connection = connection
  119
+
102 120
     def get_meta(self):
103 121
         """
104 122
         Returns the Options instance (the model._meta) from which to start
@@ -376,7 +394,8 @@ def get_columns(self, with_aliases=False):
376 394
         some cases to avoid ambiguitity with nested queries.
377 395
         """
378 396
         qn = self.quote_name_unless_alias
379  
-        result = ['(%s) AS %s' % (col, alias) for alias, col in self.extra_select.iteritems()]
  397
+        qn2 = self.connection.ops.quote_name
  398
+        result = ['(%s) AS %s' % (col, qn2(alias)) for alias, col in self.extra_select.iteritems()]
380 399
         aliases = set(self.extra_select.keys())
381 400
         if with_aliases:
382 401
             col_aliases = aliases.copy()
6  django/db/models/sql/where.py
@@ -51,12 +51,12 @@ def as_sql(self, node=None, qn=None):
51 51
                     format = '(%s)'
52 52
                 elif isinstance(child, tree.Node):
53 53
                     sql, params = self.as_sql(child, qn)
54  
-                    if len(child.children) == 1:
  54
+                    if child.negated:
  55
+                        format = 'NOT (%s)'
  56
+                    elif len(child.children) == 1:
55 57
                         format = '%s'
56 58
                     else:
57 59
                         format = '(%s)'
58  
-                    if child.negated:
59  
-                        format = 'NOT %s' % format
60 60
                 else:
61 61
                     sql, params = self.make_atom(child, qn)
62 62
                     format = '%s'
23  docs/db-api.txt
@@ -376,6 +376,29 @@ You can evaluate a ``QuerySet`` in the following ways:
376 376
       iterating over a ``QuerySet`` will take advantage of your database to
377 377
       load data and instantiate objects only as you need them.
378 378
 
  379
+
  380
+Pickling QuerySets
  381
+~~~~~~~~~~~~~~~~~~
  382
+
  383
+If you pickle_ a ``QuerySet``, this will also force all the results to be
  384
+loaded into memory prior to pickling. This is because pickling is usually used
  385
+as a precursor to caching and when the cached queryset is reloaded, you want
  386
+the results to already be present. This means that when you unpickle a
  387
+``QuerySet``, it contains the results at the moment it was pickled, rather
  388
+than the results that are currently in the database.
  389
+
  390
+If you only want to pickle the necessary information to recreate the
  391
+``Queryset`` from the database at a later time, pickle the ``query`` attribute
  392
+of the ``QuerySet``. You can then recreate the original ``QuerySet`` (without
  393
+any results loaded) using some code like this::
  394
+
  395
+    >>> import pickle
  396
+    >>> query = pickle.loads(s)     # Assuming 's' is the pickled string.
  397
+    >>> qs = MyModel.objects.all()
  398
+    >>> qs.query = query            # Restore the original 'query'.
  399
+
  400
+.. _pickle: http://docs.python.org/lib/module-pickle.html
  401
+
379 402
 Limiting QuerySets
380 403
 ------------------
381 404
 
23  docs/request_response.txt
@@ -402,6 +402,27 @@ hard-coded strings. If you use this technique, follow these guidelines:
402 402
       content, you can't use the ``HttpResponse`` instance as a file-like
403 403
       object. Doing so will raise ``Exception``.
404 404
 
  405
+Setting headers
  406
+~~~~~~~~~~~~~~~
  407
+
  408
+To set a header in your response, just treat it like a dictionary::
  409
+
  410
+    >>> response = HttpResponse()
  411
+    >>> response['Pragma'] = 'no-cache'
  412
+
  413
+Telling the browser to treat the response as a file attachment
  414
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  415
+
  416
+To tell the browser to treat the response as a file attachment, use the
  417
+``mimetype`` argument and set the ``Content-Disposition`` header. For example,
  418
+this is how you might return a Microsoft Excel spreadsheet::
  419
+
  420
+    >>> response = HttpResponse(my_data, mimetype='application/vnd.ms-excel')
  421
+    >>> response['Content-Disposition'] = 'attachment; filename=foo.xls'
  422
+
  423
+There's nothing Django-specific about the ``Content-Disposition`` header, but
  424
+it's easy to forget the syntax, so we've included it here.
  425
+
405 426
 Methods
406 427
 -------
407 428
 
@@ -420,7 +441,7 @@ Methods
420 441
     but since this is actually the value included in the HTTP ``Content-Type``
421 442
     header, it can also include the character set encoding, which makes it
422 443
     more than just a MIME type specification. If ``mimetype`` is specified
423  
-    (not None), that value is used. Otherwise, ``content_type`` is used. If
  444
+    (not ``None``), that value is used. Otherwise, ``content_type`` is used. If
424 445
     neither is given, the ``DEFAULT_CONTENT_TYPE`` setting is used.
425 446
 
426 447
 ``__setitem__(header, value)``
12  tests/modeltests/basic/models.py
@@ -398,4 +398,16 @@ def __unicode__(self):
398 398
 >>> s = set([a10, a11, a12])
399 399
 >>> Article.objects.get(headline='Article 11') in s
400 400
 True
  401
+
  402
+# The 'select' argument to extra() supports names with dashes in them, as long
  403
+# as you use values().
  404
+>>> Article.objects.filter(pub_date__year=2008).extra(select={'dashed-value': '1'}).values('headline', 'dashed-value')
  405
+[{'headline': u'Article 11', 'dashed-value': 1}, {'headline': u'Article 12', 'dashed-value': 1}]
  406
+
  407
+# If you use 'select' with extra() and names containing dashes on a query
  408
+# that's *not* a values() query, those extra 'select' values will silently be
  409
+# ignored.
  410
+>>> articles = Article.objects.filter(pub_date__year=2008).extra(select={'dashed-value': '1', 'undashedvalue': '2'})
  411
+>>> articles[0].undashedvalue
  412
+2
401 413
 """
8  tests/regressiontests/queries/models.py
@@ -120,13 +120,13 @@ class Meta:
120 120
 # A model and custom default manager combination.
121 121
 class CustomManager(models.Manager):
122 122
     def get_query_set(self):
123  
-        return super(CustomManager, self).get_query_set().filter(public=True,
124  
-                tag__name='t1')
  123
+        qs = super(CustomManager, self).get_query_set()
  124
+        return qs.filter(is_public=True, tag__name='t1')
125 125
 
126 126
 class ManagedModel(models.Model):
127 127
     data = models.CharField(max_length=10)
128 128
     tag = models.ForeignKey(Tag)
129  
-    public = models.BooleanField(default=True)
  129
+    is_public = models.BooleanField(default=True)
130 130
 
131 131
     objects = CustomManager()
132 132
     normal_manager = models.Manager()
@@ -698,7 +698,7 @@ def __unicode__(self):
698 698
 Bug #7095
699 699
 Updates that are filtered on the model being updated are somewhat tricky to get
700 700
 in MySQL. This exercises that case.
701  
->>> mm = ManagedModel.objects.create(data='mm1', tag=t1, public=True)
  701
+>>> mm = ManagedModel.objects.create(data='mm1', tag=t1, is_public=True)
702 702
 >>> ManagedModel.objects.update(data='mm')
703 703
 
704 704
 """}

0 notes on commit 5922dab

Please sign in to comment.
Something went wrong with that request. Please try again.