Re: [Django] #34699: Filtering on annotated TruncSecond expression gives unexpected result.

2023-07-21 Thread Django
#34699: Filtering on annotated TruncSecond expression gives unexpected result.
-+-
 Reporter:  Stefan   |Owner:  (none)
 Type:   |   Status:  new
  Cleanup/optimization   |
Component:  Database layer   |  Version:  4.2
  (models, ORM)  |
 Severity:  Normal   |   Resolution:
 Keywords:   | Triage Stage:  Accepted
Has patch:  0|  Needs documentation:  0
  Needs tests:  0|  Patch needs improvement:  0
Easy pickings:  0|UI/UX:  0
-+-
Changes (by Francesco Panico):

 * owner:  Francesco Panico => (none)
 * status:  assigned => new


-- 
Ticket URL: 
Django 
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-updates+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/0107018978e1fe0c-b5187c95-808a-47c0-a2e7-e2e28c6bb1c5-00%40eu-central-1.amazonses.com.


Re: [Django] #34699: Filtering on annotated TruncSecond expression gives unexpected result.

2023-07-17 Thread Django
#34699: Filtering on annotated TruncSecond expression gives unexpected result.
-+-
 Reporter:  Stefan   |Owner:  Francesco
 Type:   |  Panico
  Cleanup/optimization   |   Status:  assigned
Component:  Database layer   |  Version:  4.2
  (models, ORM)  |
 Severity:  Normal   |   Resolution:
 Keywords:   | Triage Stage:  Accepted
Has patch:  0|  Needs documentation:  0
  Needs tests:  0|  Patch needs improvement:  0
Easy pickings:  0|UI/UX:  0
-+-

Comment (by Stefan):

 @Natalia, apologies I should've said, it was PSQL 14.3.

 I want to clarify that from a purely ORM perspective the result is
 surprising, given

 {{{#!python
 Book.objects.update(published=timezone.now())
 
Book.objects.annotate(_published_trunc=TruncSecond('published')).filter(_published_trunc__lte=timezone.now()).count()
 # 0
 }}}

 the result is 0. One has to dive in to the SQL to understand why this is
 happening, and it's because `AT TIME ZONE 'Europe/Berlin'` is making the
 timezone naive in the DB level. The docs do say:

 Trunc() - "If a different timezone like Australia/Melbourne is active
 in Django, then the datetime is converted to the new timezone before the
 value is truncated."

 Although it says the datetime is converted to the new timezone before the
 value is truncated, ''converted to new timezone'' doesn't necessarily
 suggest that the resulting time zone is naive - one could still assume it
 an aware timezone just with an offset of +11:00. The latter is further
 suggested because the immediately following examples in that doc show the
 returned value on the annotation are an aware value with an offset of
 +11:00, and not naive.

-- 
Ticket URL: 
Django 
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-updates+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/01070189643eb452-5d5fb5fb-986b-4497-beb1-845bc1d76e79-00%40eu-central-1.amazonses.com.


Re: [Django] #34699: Filtering on annotated TruncSecond expression gives unexpected result.

2023-07-17 Thread Django
#34699: Filtering on annotated TruncSecond expression gives unexpected result.
-+-
 Reporter:  Stefan   |Owner:  Francesco
 Type:   |  Panico
  Cleanup/optimization   |   Status:  assigned
Component:  Database layer   |  Version:  4.2
  (models, ORM)  |
 Severity:  Normal   |   Resolution:
 Keywords:   | Triage Stage:  Accepted
Has patch:  0|  Needs documentation:  0
  Needs tests:  0|  Patch needs improvement:  0
Easy pickings:  0|UI/UX:  0
-+-

Comment (by Natalia Bidart):

 Replying to [comment:9 Mariusz Felisiak]:
 > It works as documented:
 > - `timezone.now()` - ''"If USE_TZ is True, this will be an aware
 datetime representing the **current time in UTC**. Note that now() will
 always return times in UTC regardless of the value of TIME_ZONE; you can
 use localtime() to get the time in the current time zone."''
 > - `Trunc()` - ''"If a different timezone like Australia/Melbourne is
 active in Django, then the datetime **is converted to the new timezone**
 before the value is truncated."''

 Right, I understand the docs above and how that match the results I got.
 But, at the same time, the first paragraph about "Time Zones" says:

 ''When support for time zones is enabled, Django stores datetime
 information in UTC in the database, uses time-zone-aware datetime objects
 internally, and translates them to the end user’s time zone in templates
 and forms.
 [...]
 Even if your website is available in only one time zone, it’s still good
 practice to store data in UTC in your database.''

 The above aligns perfectly (and makes sense) with `timezone.now` returning
 an aware datetime in UTC. But then, at least to me, is quite surprising
 that `TruncSecond`, which is an operation fully occurring in the DB, would
 not "respect" that "UTC invariant" and have the `TIME_ZONE` setting
 affecting the results. Does my point make sense? Do you have historic
 information about why `TruncSecond` (and related functions) would not
 operate with/keep the tz defined in the datetime being processed?

-- 
Ticket URL: 
Django 
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-updates+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/010701896405df60-757fb278-9734-496c-897c-36577b0522bd-00%40eu-central-1.amazonses.com.


Re: [Django] #34699: Filtering on annotated TruncSecond expression gives unexpected result.

2023-07-17 Thread Django
#34699: Filtering on annotated TruncSecond expression gives unexpected result.
-+-
 Reporter:  Stefan   |Owner:  Francesco
 Type:   |  Panico
  Cleanup/optimization   |   Status:  assigned
Component:  Database layer   |  Version:  4.2
  (models, ORM)  |
 Severity:  Normal   |   Resolution:
 Keywords:   | Triage Stage:  Accepted
Has patch:  0|  Needs documentation:  0
  Needs tests:  0|  Patch needs improvement:  0
Easy pickings:  0|UI/UX:  0
-+-

Comment (by Mariusz Felisiak):

 It works as documented:
 - `timezone.now()` - ''"If USE_TZ is True, this will be an aware datetime
 representing the **current time in UTC**. Note that now() will always
 return times in UTC regardless of the value of TIME_ZONE; you can use
 localtime() to get the time in the current time zone."''
 - `Trunc()` - ''"If a different timezone like Australia/Melbourne is
 active in Django, then the datetime **is converted to the new timezone**
 before the value is truncated."''

-- 
Ticket URL: 
Django 
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-updates+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/0107018963b6b015-81d487f6-48d9-4507-a9de-d502e0f79841-00%40eu-central-1.amazonses.com.


Re: [Django] #34699: Filtering on annotated TruncSecond expression gives unexpected result.

2023-07-17 Thread Django
#34699: Filtering on annotated TruncSecond expression gives unexpected result.
-+-
 Reporter:  Stefan   |Owner:  Francesco
 Type:   |  Panico
  Cleanup/optimization   |   Status:  assigned
Component:  Database layer   |  Version:  4.2
  (models, ORM)  |
 Severity:  Normal   |   Resolution:
 Keywords:   | Triage Stage:  Accepted
Has patch:  0|  Needs documentation:  0
  Needs tests:  0|  Patch needs improvement:  0
Easy pickings:  0|UI/UX:  0
-+-

Comment (by Natalia Bidart):

 Thanks Mariusz for your insight. I was wondering what are your thoughts
 for my example above, where the result of calling `TruncSecond` on a
 timestamp would have a timezone different than the argument.

-- 
Ticket URL: 
Django 
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-updates+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/0107018963ae846e-e56c6c9a-3b31-484a-9b9e-624fa6b30e68-00%40eu-central-1.amazonses.com.


Re: [Django] #34699: Filtering on annotated TruncSecond expression gives unexpected result.

2023-07-15 Thread Django
#34699: Filtering on annotated TruncSecond expression gives unexpected result.
-+-
 Reporter:  Stefan   |Owner:  Francesco
 Type:   |  Panico
  Cleanup/optimization   |   Status:  assigned
Component:  Database layer   |  Version:  4.2
  (models, ORM)  |
 Severity:  Normal   |   Resolution:
 Keywords:   | Triage Stage:  Accepted
Has patch:  0|  Needs documentation:  0
  Needs tests:  0|  Patch needs improvement:  0
Easy pickings:  0|UI/UX:  0
-+-

Comment (by Mariusz Felisiak):

 I'm pretty sure it's not a valid ticket, but couldn't find quickly find a
 proper justification. Any change to the current behavior would be backward
 incompatible.

-- 
Ticket URL: 
Django 
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-updates+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/010701895aa36fbd-4f80c165-2761-465b-8020-412011e95ded-00%40eu-central-1.amazonses.com.


Re: [Django] #34699: Filtering on annotated TruncSecond expression gives unexpected result.

2023-07-14 Thread Django
#34699: Filtering on annotated TruncSecond expression gives unexpected result.
-+-
 Reporter:  Stefan   |Owner:  Francesco
 Type:   |  Panico
  Cleanup/optimization   |   Status:  assigned
Component:  Database layer   |  Version:  4.2
  (models, ORM)  |
 Severity:  Normal   |   Resolution:
 Keywords:   | Triage Stage:  Accepted
Has patch:  0|  Needs documentation:  0
  Needs tests:  0|  Patch needs improvement:  0
Easy pickings:  0|UI/UX:  0
-+-
Changes (by Natalia Bidart):

 * type:  Uncategorized => Cleanup/optimization
 * stage:  Unreviewed => Accepted


Comment:

 I did some more research on this. I'm accepting this ticket because I do
 believe there is an unexpected behavior, which may be a bug or just a
 documentation issue.

 The simplest test of getting all books and printing their `published` date
 and their truncated-to-seconds published date is, IMHO, unexpected: the
 `published` value is in UTC but the annotated value is in the timezone the
 app is configured. My settings:

 {{{
 USE_TZ = True
 TIME_ZONE = "Europe/Berlin"
 }}}

 The model:

 {{{
 from django.db import models
 from django.utils import timezone


 class Book(models.Model):
 published = models.DateTimeField(default=timezone.now)
 }}}

 In the shell:
 {{{
 import time
 from django.db.models.functions import TruncSecond
 from testapp.models import Book
 for i in range(3):
 Book.objects.create(); time.sleep(1)
 annotated_books =
 Book.objects.annotate(_published_trunc=TruncSecond('published'))
 for i in annotated_books.all():
 print(i.published, i._published_trunc)
 }}}

 With output:
 {{{
 2023-07-14 18:39:22.620603+00:00 2023-07-14 20:39:22+02:00
 2023-07-14 18:39:28.585856+00:00 2023-07-14 20:39:28+02:00
 2023-07-14 18:39:29.590469+00:00 2023-07-14 20:39:29+02:00
 2023-07-14 18:39:30.595811+00:00 2023-07-14 20:39:30+02:00
 }}}

-- 
Ticket URL: 
Django 
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-updates+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/0107018955c43298-5f8bdd89-8b47-4bff-bf14-54dea8795a3a-00%40eu-central-1.amazonses.com.


Re: [Django] #34699: Filtering on annotated TruncSecond expression gives unexpected result.

2023-07-13 Thread Django
#34699: Filtering on annotated TruncSecond expression gives unexpected result.
-+-
 Reporter:  Stefan   |Owner:  Francesco
 |  Panico
 Type:  Uncategorized|   Status:  assigned
Component:  Database layer   |  Version:  4.2
  (models, ORM)  |
 Severity:  Normal   |   Resolution:
 Keywords:   | Triage Stage:
 |  Unreviewed
Has patch:  0|  Needs documentation:  0
  Needs tests:  0|  Patch needs improvement:  0
Easy pickings:  0|UI/UX:  0
-+-

Comment (by Natalia Bidart):

 Also @stefan, what database are you using in your example? Thanks!

-- 
Ticket URL: 
Django 
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-updates+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/01070189520e6eac-20012dfb-3ba4-4b2b-8e72-f86b9300983d-00%40eu-central-1.amazonses.com.


Re: [Django] #34699: Filtering on annotated TruncSecond expression gives unexpected result.

2023-07-13 Thread Django
#34699: Filtering on annotated TruncSecond expression gives unexpected result.
-+-
 Reporter:  Stefan   |Owner:  Francesco
 |  Panico
 Type:  Uncategorized|   Status:  assigned
Component:  Database layer   |  Version:  4.2
  (models, ORM)  |
 Severity:  Normal   |   Resolution:
 Keywords:   | Triage Stage:
 |  Unreviewed
Has patch:  0|  Needs documentation:  0
  Needs tests:  0|  Patch needs improvement:  0
Easy pickings:  0|UI/UX:  0
-+-

Comment (by Natalia Bidart):

 I've been trying to understand this report to properly triage it. From the
 docs for `Trunc` and derivatives, when describing
 [https://docs.djangoproject.com/en/4.2/ref/models/database-functions
 /#datetimefield-truncation DateTimeField truncation], the example given
 shows this:

 {{{
  >>> Experiment.objects.annotate(
 ... date=TruncDate("start_datetime"),
 ... day=TruncDay("start_datetime", tzinfo=melb),
 ... hour=TruncHour("start_datetime", tzinfo=melb),
 ... minute=TruncMinute("start_datetime"),
 ... second=TruncSecond("start_datetime"),
 ... ).values("date", "day", "hour", "minute", "second").get()
 {'date': datetime.date(2014, 6, 15),
  'day': datetime.datetime(2014, 6, 16, 0, 0,
 tzinfo=zoneinfo.ZoneInfo('Australia/Melbourne')),
  'hour': datetime.datetime(2014, 6, 16, 0, 0,
 tzinfo=zoneinfo.ZoneInfo('Australia/Melbourne')),
  'minute': 'minute': datetime.datetime(2014, 6, 15, 14, 30,
 tzinfo=timezone.utc),
  'second': datetime.datetime(2014, 6, 15, 14, 30, 50, tzinfo=timezone.utc)
 }
 }}}

 The text and examples seem to indicate that when the stored datetime is in
 a given timezone, that tz would be used in the truncation unless otherwise
 specified by the `tzinfo` param.

 @stefan, can you double check that the values for `published` are actually
 datetimes in the tz you configured you app?

-- 
Ticket URL: 
Django 
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-updates+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/01070189520d743a-102a1706-be0e-40b1-b08a-a8de06bf6be8-00%40eu-central-1.amazonses.com.


Re: [Django] #34699: Filtering on annotated TruncSecond expression gives unexpected result.

2023-07-07 Thread Django
#34699: Filtering on annotated TruncSecond expression gives unexpected result.
-+-
 Reporter:  Stefan   |Owner:  Francesco
 |  Panico
 Type:  Uncategorized|   Status:  assigned
Component:  Database layer   |  Version:  4.2
  (models, ORM)  |
 Severity:  Normal   |   Resolution:
 Keywords:   | Triage Stage:
 |  Unreviewed
Has patch:  0|  Needs documentation:  0
  Needs tests:  0|  Patch needs improvement:  0
Easy pickings:  0|UI/UX:  0
-+-
Changes (by Francesco Panico):

 * owner:  nobody => Francesco Panico
 * status:  new => assigned


-- 
Ticket URL: 
Django 
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-updates+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/01070189324188a3-b09c4866-d9de-4811-a551-296c277fc5db-00%40eu-central-1.amazonses.com.


Re: [Django] #34699: Filtering on annotated TruncSecond expression gives unexpected result.

2023-07-07 Thread Django
#34699: Filtering on annotated TruncSecond expression gives unexpected result.
-+-
 Reporter:  Stefan   |Owner:  nobody
 Type:  Uncategorized|   Status:  new
Component:  Database layer   |  Version:  4.2
  (models, ORM)  |
 Severity:  Normal   |   Resolution:
 Keywords:   | Triage Stage:
 |  Unreviewed
Has patch:  0|  Needs documentation:  0
  Needs tests:  0|  Patch needs improvement:  0
Easy pickings:  0|UI/UX:  0
-+-

Comment (by Abdulla):

 I believe this would be the case for all other Trunc Date expressions as
 they are subclassed with `TruncBase`.
 Replying to [ticket:34699 Stefan]:
 > With a non-UTC time zone:
 >
 > {{{#!python
 >   TIME_ZONE = 'Europe/Berlin'
 >   }}}
 >
 > and a simply query like so
 >
 > {{{#!python
 >   from django.db.models.functions import TruncSecond
 >   from django.utils import timezone
 >
 >   book = Book.objects.get(id=2)
 >   now = timezone.now()
 >   book.published = now
 >   book.save()
 >
 Book.objects.annotate(_published_trunc=TruncSecond('published')).filter(id=2,
 _published_trunc__lte=now)
 >   }}}
 >
 > The result is empty; I have simply filtered `now` against a second-
 trunced version of `now` so I would expect a result.
 >
 > However under the hood the `_published_now` column is converted to a
 naive timestamp using `AT TIME ZONE 'Europe/Berlin'` and is thus a naive
 timestamp 2 hours ''ahead'' of UTC.
 >
 > {{{#!sql
 > SELECT "book"."id",
 >"book"."published",
 >DATE_TRUNC('second', "book"."published" AT TIME ZONE
 'Europe/Berlin') AS "_published_trunc"
 > FROM "book"
 > WHERE ("book"."id" = 2 AND
 >DATE_TRUNC('second', "book"."_published_trunc" AT TIME ZONE
 'Europe/Berlin') <=
 >'2023-07-04 11:59:00+02:00'::timestamptz)
 > }}}
 >
 >
 > The filter compares a naive timestamp to an aware one, but assumes the
 LHS naive timestamp is a UTC timestamp - which it is not, it is Berlin
 time.
 >
 > **Workaround**
 >
 > 1) Use `TruncSecond(now)` in the filter so the compared naive timestamps
 are the same.
 >
 > 2) Use `_published_trunc=TruncSecond('published',
 tzinfo=datetime.timezone.utc)` - I don't like this though. It's not clear
 without a comment why the tzinfo is needed ''and'' it assumes the database
 will compare timezones using UTC.

-- 
Ticket URL: 
Django 
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-updates+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/010701893228280c-d6873e19-29ef-4fc8-b388-311648278491-00%40eu-central-1.amazonses.com.


Re: [Django] #34699: Filtering on annotated TruncSecond expression gives unexpected result.

2023-07-07 Thread Django
#34699: Filtering on annotated TruncSecond expression gives unexpected result.
-+-
 Reporter:  Stefan   |Owner:  nobody
 Type:  Uncategorized|   Status:  new
Component:  Database layer   |  Version:  4.2
  (models, ORM)  |
 Severity:  Normal   |   Resolution:
 Keywords:   | Triage Stage:
 |  Unreviewed
Has patch:  0|  Needs documentation:  0
  Needs tests:  0|  Patch needs improvement:  0
Easy pickings:  0|UI/UX:  0
-+-
Changes (by Mariusz Felisiak):

 * cc: Aymeric Augustin (added)
 * component:  Uncategorized => Database layer (models, ORM)


-- 
Ticket URL: 
Django 
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-updates+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/010701893003dfd2-4074e408-0c7f-4ba3-9b30-9e45d01fce9c-00%40eu-central-1.amazonses.com.


[Django] #34699: Filtering on annotated TruncSecond expression gives unexpected result.

2023-07-07 Thread Django
#34699: Filtering on annotated TruncSecond expression gives unexpected result.
--+
   Reporter:  StefanCardnell  |  Owner:  nobody
   Type:  Uncategorized   | Status:  new
  Component:  Uncategorized   |Version:  4.2
   Severity:  Normal  |   Keywords:
   Triage Stage:  Unreviewed  |  Has patch:  0
Needs documentation:  0   |Needs tests:  0
Patch needs improvement:  0   |  Easy pickings:  0
  UI/UX:  0   |
--+
 With a non-UTC time zone:

 {{{#!python
   TIME_ZONE = 'Europe/Berlin'
   }}}

 and a simply query like so

 {{{#!python
   from django.db.models.functions import TruncSecond
   from django.utils import timezone

   book = Book.objects.get(id=2)
   now = timezone.now()
   book.published = now
   book.save()
 Book.objects.annotate(_published_trunc=TruncSecond('published')).filter(id=2,
 _published_trunc__lte=now)
   }}}

 The result is empty; I have simply filtered `now` against a second-trunced
 version of `now` so I would expect a result.

 However under the hood the `_published_now` column is converted to a naive
 timestamp using `AT TIME ZONE 'Europe/Berlin'` and is thus a naive
 timestamp 2 hours ''ahead'' of UTC.

 {{{#!sql
 SELECT "book"."id",
"book"."published",
DATE_TRUNC('second', "book"."published" AT TIME ZONE
 'Europe/Berlin') AS "_published_trunc"
 FROM "book"
 WHERE ("book"."id" = 2 AND
DATE_TRUNC('second', "book"."_published_trunc" AT TIME ZONE
 'Europe/Berlin') <=
'2023-07-04 11:59:00+02:00'::timestamptz)
 }}}


 The filter compares a naive timestamp to an aware one, but assumes the LHS
 naive timestamp is a UTC timestamp - which it is not, it is Berlin time.

 **Workaround**

 1) Use `TruncSecond(now)` in the filter so the compared naive timestamps
 are the same.

 2) Use `_published_trunc=TruncSecond('published',
 tzinfo=datetime.timezone.utc)` - I don't like this though. It's not clear
 without a comment why the tzinfo is needed ''and'' it assumes the database
 will compare timezones using UTC.

-- 
Ticket URL: 
Django 
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-updates+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/010701892f638bec-b87c84eb-8c82-4159-bf30-71288779af8e-00%40eu-central-1.amazonses.com.