mirror of
https://github.com/django/django.git
synced 2025-07-05 18:29:11 +00:00
queryset-refactor: Merged changes from trunk up to [7085].
git-svn-id: http://code.djangoproject.com/svn/django/branches/queryset-refactor@7086 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
a4343209db
commit
0a9b751958
8
AUTHORS
8
AUTHORS
@ -45,6 +45,8 @@ answer newbie questions, and generally made Django that much better:
|
||||
Marty Alchin <gulopine@gamemusic.org>
|
||||
Daniel Alves Barbosa de Oliveira Vaz <danielvaz@gmail.com>
|
||||
AgarFu <heaven@croasanaso.sytes.net>
|
||||
Dagur Páll Ammendrup <dagurp@gmail.com>
|
||||
Collin Anderson <cmawebsite@gmail.com>
|
||||
Andreas
|
||||
andy@jadedplanet.net
|
||||
Fabrice Aneche <akh@nobugware.com>
|
||||
@ -52,7 +54,7 @@ answer newbie questions, and generally made Django that much better:
|
||||
Florian Apolloner
|
||||
arien <regexbot@gmail.com>
|
||||
David Ascher <http://ascher.ca/>
|
||||
david@kazserve.org
|
||||
Jökull Sólberg Auðunsson <jokullsolberg@gmail.com>
|
||||
Arthur <avandorp@gmail.com>
|
||||
axiak@mit.edu
|
||||
Jiri Barton
|
||||
@ -99,6 +101,7 @@ answer newbie questions, and generally made Django that much better:
|
||||
Dirk Datzert <dummy@habmalnefrage.de>
|
||||
Jonathan Daugherty (cygnus) <http://www.cprogrammer.org/>
|
||||
dave@thebarproject.com
|
||||
david@kazserve.org
|
||||
Jason Davies (Esaj) <http://www.jasondavies.com/>
|
||||
Alex Dedul
|
||||
deric@monowerks.com
|
||||
@ -228,7 +231,7 @@ answer newbie questions, and generally made Django that much better:
|
||||
mccutchen@gmail.com
|
||||
michael.mcewan@gmail.com
|
||||
michal@plovarna.cz
|
||||
mikko@sorl.net
|
||||
Mikko Hellsing <mikko@sorl.net>
|
||||
Slawek Mikula <slawek dot mikula at gmail dot com>
|
||||
mitakummaa@gmail.com
|
||||
mmarshall
|
||||
@ -301,6 +304,7 @@ answer newbie questions, and generally made Django that much better:
|
||||
Don Spaulding <donspauldingii@gmail.com>
|
||||
Bjørn Stabell <bjorn@exoweb.net>
|
||||
Georgi Stanojevski <glisha@gmail.com>
|
||||
starrynight <cmorgh@gmail.com>
|
||||
Vasiliy Stavenko <stavenko@gmail.com>
|
||||
Thomas Steinacher <http://www.eggdrop.ch/>
|
||||
Johan C. Stöver <johan@nilling.nl>
|
||||
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@ -9,14 +9,14 @@ msgstr ""
|
||||
"Project-Id-Version: djangojs\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2007-05-20 18:25+0200\n"
|
||||
"PO-Revision-Date: 2007-12-01 12:06+0100\n"
|
||||
"Last-Translator: Antoni Aloy <antoni.aloy@trespams.com>\n"
|
||||
"PO-Revision-Date: 2008-01-22 19:39+0100\n"
|
||||
"Last-Translator: Marc Garcia <marc.garcia@accopensys.com>\n"
|
||||
"Language-Team: español <ca@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: KBabel 1.11.4\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:33
|
||||
#, perl-format
|
||||
@ -50,9 +50,7 @@ msgstr "Deseleccionar tots"
|
||||
|
||||
#: contrib/admin/media/js/dateparse.js:32
|
||||
#: contrib/admin/media/js/calendar.js:24
|
||||
msgid ""
|
||||
"January February March April May June July August September October November "
|
||||
"December"
|
||||
msgid "January February March April May June July August September October November December"
|
||||
msgstr "Gener Febrer Març Abril Maig Juny Juliol Agost Setembre Octubre Novembre Desembre"
|
||||
|
||||
#: contrib/admin/media/js/dateparse.js:33
|
||||
@ -61,7 +59,7 @@ msgstr "Diumenge Dilluns Dimarts Dimecres Dijous Divendres Dissabte"
|
||||
|
||||
#: contrib/admin/media/js/calendar.js:25
|
||||
msgid "S M T W T F S"
|
||||
msgstr "D L M X J V S"
|
||||
msgstr "Dg Dl Dt Dc Dj Dv Ds"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:47
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:81
|
||||
|
Binary file not shown.
@ -2614,6 +2614,34 @@ msgstr "Samstag"
|
||||
msgid "Sunday"
|
||||
msgstr "Sonntag"
|
||||
|
||||
#: utils/dates.py:10
|
||||
msgid "Mon"
|
||||
msgstr "Mo"
|
||||
|
||||
#: utils/dates.py:10
|
||||
msgid "Tue"
|
||||
msgstr "Di"
|
||||
|
||||
#: utils/dates.py:10
|
||||
msgid "Wed"
|
||||
msgstr "Mi"
|
||||
|
||||
#: utils/dates.py:10
|
||||
msgid "Thu"
|
||||
msgstr "Do"
|
||||
|
||||
#: utils/dates.py:10
|
||||
msgid "Fri"
|
||||
msgstr "Fr"
|
||||
|
||||
#: utils/dates.py:11
|
||||
msgid "Sat"
|
||||
msgstr "Sa"
|
||||
|
||||
#: utils/dates.py:11
|
||||
msgid "Sun"
|
||||
msgstr "So"
|
||||
|
||||
#: utils/dates.py:14
|
||||
msgid "January"
|
||||
msgstr "Januar"
|
||||
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@ -8,8 +8,8 @@ msgstr ""
|
||||
"Project-Id-Version: django 1.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2007-09-14 12:33+0100\n"
|
||||
"PO-Revision-Date: 2007-09-14 14:19+0100\n"
|
||||
"Last-Translator: Michael Thornhill <michael.thornhill@gmail.com>\n"
|
||||
"PO-Revision-Date: 2008-01-23 11:04+0100\n"
|
||||
"Last-Translator: Michael Thornhill <michael@maithu.com>\n"
|
||||
"Language-Team: Gaeilge <ga@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
@ -18,99 +18,99 @@ msgstr ""
|
||||
#: contrib/admin/media/js/calendar.js:24
|
||||
#: contrib/admin/media/js/dateparse.js:32
|
||||
msgid "January February March April May June July August September October November December"
|
||||
msgstr ""
|
||||
msgstr "Eanair Feabhra Márta Aibreán Bealtaine Meitheamh Iúil Lúnasa Mean Fómhair Deireadh Fómhair Nollaig"
|
||||
|
||||
#: contrib/admin/media/js/calendar.js:25
|
||||
msgid "S M T W T F S"
|
||||
msgstr ""
|
||||
msgstr "D L M C D A S"
|
||||
|
||||
#: contrib/admin/media/js/dateparse.js:33
|
||||
msgid "Sunday Monday Tuesday Wednesday Thursday Friday Saturday"
|
||||
msgstr ""
|
||||
msgstr "Domhnaigh Luain Máirt Céadaoin Déardaoin Aoine Sathairn"
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:33
|
||||
#, perl-format
|
||||
msgid "Available %s"
|
||||
msgstr ""
|
||||
msgstr "%s ar fáil"
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:41
|
||||
msgid "Choose all"
|
||||
msgstr ""
|
||||
msgstr "Roghnaigh iomlán"
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:46
|
||||
msgid "Add"
|
||||
msgstr ""
|
||||
msgstr "Cuir le"
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:48
|
||||
msgid "Remove"
|
||||
msgstr ""
|
||||
msgstr "Bain amach"
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:53
|
||||
#, perl-format
|
||||
msgid "Chosen %s"
|
||||
msgstr ""
|
||||
msgstr "Roghnófar %s"
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:54
|
||||
msgid "Select your choice(s) and click "
|
||||
msgstr ""
|
||||
msgstr "Roghnaigh do rogha agus cniog"
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:59
|
||||
msgid "Clear all"
|
||||
msgstr ""
|
||||
msgstr "Glan iomlán"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:47
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:81
|
||||
msgid "Now"
|
||||
msgstr ""
|
||||
msgstr "Anois"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:51
|
||||
msgid "Clock"
|
||||
msgstr ""
|
||||
msgstr "Clog"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:78
|
||||
msgid "Choose a time"
|
||||
msgstr ""
|
||||
msgstr "Roghnaigh am"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:82
|
||||
msgid "Midnight"
|
||||
msgstr ""
|
||||
msgstr "Meán oíche"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:83
|
||||
msgid "6 a.m."
|
||||
msgstr ""
|
||||
msgstr "6 a.m."
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:84
|
||||
msgid "Noon"
|
||||
msgstr ""
|
||||
msgstr "Nóin"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:88
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:183
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
msgstr "Cealaigh"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:128
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:177
|
||||
msgid "Today"
|
||||
msgstr ""
|
||||
msgstr "Inniu"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:132
|
||||
msgid "Calendar"
|
||||
msgstr ""
|
||||
msgstr "Féilire"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:175
|
||||
msgid "Yesterday"
|
||||
msgstr ""
|
||||
msgstr "Inné"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:179
|
||||
msgid "Tomorrow"
|
||||
msgstr ""
|
||||
msgstr "Amárach"
|
||||
|
||||
#: contrib/admin/media/js/admin/CollapsedFieldsets.js:34
|
||||
#: contrib/admin/media/js/admin/CollapsedFieldsets.js:72
|
||||
msgid "Show"
|
||||
msgstr ""
|
||||
msgstr "Taispeán"
|
||||
|
||||
#: contrib/admin/media/js/admin/CollapsedFieldsets.js:63
|
||||
msgid "Hide"
|
||||
msgstr ""
|
||||
msgstr "Folaigh"
|
||||
|
||||
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@ -6,8 +6,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: djangojs\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2007-03-06 02:29+0100\n"
|
||||
"PO-Revision-Date: 2007-03-06 10:30+0100\n"
|
||||
"POT-Creation-Date: 2008-02-01 15:31+0100\n"
|
||||
"PO-Revision-Date: 2008-02-01 15:32+0100\n"
|
||||
"Last-Translator: Mikko Hellsing <mikko@sorl.net>\n"
|
||||
"Language-Team: Django I18N <Django-I18N@googlegroups.com>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@ -20,7 +20,7 @@ msgstr ""
|
||||
#: contrib/admin/media/js/SelectFilter2.js:33
|
||||
#, perl-format
|
||||
msgid "Available %s"
|
||||
msgstr "Tillgänglig %s"
|
||||
msgstr "Tillgängliga %s"
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:41
|
||||
msgid "Choose all"
|
||||
@ -37,7 +37,7 @@ msgstr "Ta bort"
|
||||
#: contrib/admin/media/js/SelectFilter2.js:53
|
||||
#, perl-format
|
||||
msgid "Chosen %s"
|
||||
msgstr "Vald %s"
|
||||
msgstr "Valda %s"
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:54
|
||||
msgid "Select your choice(s) and click "
|
||||
@ -47,8 +47,8 @@ msgstr "Gör dina val och klicka på "
|
||||
msgid "Clear all"
|
||||
msgstr "Ta bort alla"
|
||||
|
||||
#: contrib/admin/media/js/dateparse.js:32
|
||||
#: contrib/admin/media/js/calendar.js:24
|
||||
#: contrib/admin/media/js/dateparse.js:32
|
||||
msgid ""
|
||||
"January February March April May June July August September October November "
|
||||
"December"
|
||||
@ -56,14 +56,14 @@ msgstr ""
|
||||
"Januari Februari Mars April Maj Juni Juli Augusti September Oktober November "
|
||||
"December"
|
||||
|
||||
#: contrib/admin/media/js/dateparse.js:33
|
||||
msgid "Sunday Monday Tuesday Wednesday Thursday Friday Saturday"
|
||||
msgstr "Söndag Måndag Tisdag Onsdag Torsdag Fredag Lördag"
|
||||
|
||||
#: contrib/admin/media/js/calendar.js:25
|
||||
msgid "S M T W T F S"
|
||||
msgstr "S M T O T F L"
|
||||
|
||||
#: contrib/admin/media/js/dateparse.js:33
|
||||
msgid "Sunday Monday Tuesday Wednesday Thursday Friday Saturday"
|
||||
msgstr "Söndag Måndag Tisdag Onsdag Torsdag Fredag Lördag"
|
||||
|
||||
#: contrib/admin/media/js/admin/CollapsedFieldsets.js:34
|
||||
#: contrib/admin/media/js/admin/CollapsedFieldsets.js:72
|
||||
msgid "Show"
|
||||
@ -118,5 +118,4 @@ msgstr "Igår"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:179
|
||||
msgid "Tomorrow"
|
||||
msgstr "I morgon"
|
||||
|
||||
msgstr "Imorgon"
|
||||
|
@ -18,7 +18,7 @@ DATABASE_PORT = '' # Set to empty string for default. Not used with
|
||||
|
||||
# Local time zone for this installation. Choices can be found here:
|
||||
# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
|
||||
# although not all choices may be avilable on all operating systems.
|
||||
# although not all choices may be available on all operating systems.
|
||||
# If running in a Windows environment this must be set to the same as your
|
||||
# system time zone.
|
||||
TIME_ZONE = 'America/Chicago'
|
||||
|
@ -1,5 +1,5 @@
|
||||
from django.conf.urls.defaults import *
|
||||
|
||||
urlpatterns = patterns('django.views',
|
||||
(r'^(?P<content_type_id>\d+)/(?P<object_id>\d+)/$', 'defaults.shortcut'),
|
||||
(r'^(?P<content_type_id>\d+)/(?P<object_id>.*)/$', 'defaults.shortcut'),
|
||||
)
|
||||
|
@ -34,7 +34,7 @@
|
||||
{% for bound_field_set in bound_field_sets %}
|
||||
<fieldset class="module aligned {{ bound_field_set.classes }}">
|
||||
{% if bound_field_set.name %}<h2>{{ bound_field_set.name }}</h2>{% endif %}
|
||||
{% if bound_field_set.description %}<div class="description">{{ bound_field_set.description }}</div>{% endif %}
|
||||
{% if bound_field_set.description %}<div class="description">{{ bound_field_set.description|safe }}</div>{% endif %}
|
||||
{% for bound_field_line in bound_field_set %}
|
||||
{% admin_field_line bound_field_line %}
|
||||
{% for bound_field in bound_field_line %}
|
||||
|
@ -8,7 +8,7 @@ else:
|
||||
|
||||
urlpatterns = patterns('',
|
||||
('^$', 'django.contrib.admin.views.main.index'),
|
||||
('^r/(\d+)/(.*)/$', 'django.views.defaults.shortcut'),
|
||||
('^r/', include('django.conf.urls.shortcut')),
|
||||
('^jsi18n/$', i18n_view, {'packages': 'django.conf'}),
|
||||
('^logout/$', 'django.contrib.auth.views.logout'),
|
||||
('^password_change/$', 'django.contrib.auth.views.password_change'),
|
||||
|
@ -1,25 +1,27 @@
|
||||
import datetime
|
||||
|
||||
from django.db import models
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.contrib.sites.models import Site
|
||||
from django.contrib.auth.models import User
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.conf import settings
|
||||
import datetime
|
||||
|
||||
MIN_PHOTO_DIMENSION = 5
|
||||
MAX_PHOTO_DIMENSION = 1000
|
||||
|
||||
# option codes for comment-form hidden fields
|
||||
# Option codes for comment-form hidden fields.
|
||||
PHOTOS_REQUIRED = 'pr'
|
||||
PHOTOS_OPTIONAL = 'pa'
|
||||
RATINGS_REQUIRED = 'rr'
|
||||
RATINGS_OPTIONAL = 'ra'
|
||||
IS_PUBLIC = 'ip'
|
||||
|
||||
# what users get if they don't have any karma
|
||||
# What users get if they don't have any karma.
|
||||
DEFAULT_KARMA = 5
|
||||
KARMA_NEEDED_BEFORE_DISPLAYED = 3
|
||||
|
||||
|
||||
class CommentManager(models.Manager):
|
||||
def get_security_hash(self, options, photo_options, rating_options, target):
|
||||
"""
|
||||
@ -61,7 +63,9 @@ class CommentManager(models.Manager):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
class Comment(models.Model):
|
||||
"""A comment by a registered user."""
|
||||
user = models.ForeignKey(User, raw_id_admin=True)
|
||||
content_type = models.ForeignKey(ContentType)
|
||||
object_id = models.IntegerField(_('object ID'))
|
||||
@ -86,10 +90,12 @@ class Comment(models.Model):
|
||||
is_removed = models.BooleanField(_('is removed'), help_text=_('Check this box if the comment is inappropriate. A "This comment has been removed" message will be displayed instead.'))
|
||||
site = models.ForeignKey(Site)
|
||||
objects = CommentManager()
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('comment')
|
||||
verbose_name_plural = _('comments')
|
||||
ordering = ('-submit_date',)
|
||||
|
||||
class Admin:
|
||||
fields = (
|
||||
(None, {'fields': ('content_type', 'object_id', 'site')}),
|
||||
@ -134,7 +140,7 @@ class Comment(models.Model):
|
||||
get_content_object.short_description = _('Content object')
|
||||
|
||||
def _fill_karma_cache(self):
|
||||
"Helper function that populates good/bad karma caches"
|
||||
"""Helper function that populates good/bad karma caches."""
|
||||
good, bad = 0, 0
|
||||
for k in self.karmascore_set:
|
||||
if k.score == -1:
|
||||
@ -163,8 +169,9 @@ class Comment(models.Model):
|
||||
{'user': self.user.username, 'date': self.submit_date,
|
||||
'comment': self.comment, 'domain': self.site.domain, 'url': self.get_absolute_url()}
|
||||
|
||||
|
||||
class FreeComment(models.Model):
|
||||
# A FreeComment is a comment by a non-registered user.
|
||||
"""A comment by a non-registered user."""
|
||||
content_type = models.ForeignKey(ContentType)
|
||||
object_id = models.IntegerField(_('object ID'))
|
||||
comment = models.TextField(_('comment'), max_length=3000)
|
||||
@ -175,10 +182,12 @@ class FreeComment(models.Model):
|
||||
# TODO: Change this to is_removed, like Comment
|
||||
approved = models.BooleanField(_('approved by staff'))
|
||||
site = models.ForeignKey(Site)
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('free comment')
|
||||
verbose_name_plural = _('free comments')
|
||||
ordering = ('-submit_date',)
|
||||
|
||||
class Admin:
|
||||
fields = (
|
||||
(None, {'fields': ('content_type', 'object_id', 'site')}),
|
||||
@ -212,6 +221,7 @@ class FreeComment(models.Model):
|
||||
|
||||
get_content_object.short_description = _('Content object')
|
||||
|
||||
|
||||
class KarmaScoreManager(models.Manager):
|
||||
def vote(self, user_id, comment_id, score):
|
||||
try:
|
||||
@ -233,12 +243,14 @@ class KarmaScoreManager(models.Manager):
|
||||
return DEFAULT_KARMA
|
||||
return int(round((4.5 * score) + 5.5))
|
||||
|
||||
|
||||
class KarmaScore(models.Model):
|
||||
user = models.ForeignKey(User)
|
||||
comment = models.ForeignKey(Comment)
|
||||
score = models.SmallIntegerField(_('score'), db_index=True)
|
||||
scored_date = models.DateTimeField(_('score date'), auto_now=True)
|
||||
objects = KarmaScoreManager()
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('karma score')
|
||||
verbose_name_plural = _('karma scores')
|
||||
@ -247,6 +259,7 @@ class KarmaScore(models.Model):
|
||||
def __unicode__(self):
|
||||
return _("%(score)d rating by %(user)s") % {'score': self.score, 'user': self.user}
|
||||
|
||||
|
||||
class UserFlagManager(models.Manager):
|
||||
def flag(self, comment, user):
|
||||
"""
|
||||
@ -257,7 +270,7 @@ class UserFlagManager(models.Manager):
|
||||
if int(comment.user_id) == int(user.id):
|
||||
return # A user can't flag his own comment. Fail silently.
|
||||
try:
|
||||
f = self.objects.get(user__pk=user.id, comment__pk=comment.id)
|
||||
f = self.get(user__pk=user.id, comment__pk=comment.id)
|
||||
except self.model.DoesNotExist:
|
||||
from django.core.mail import mail_managers
|
||||
f = self.model(None, user.id, comment.id, None)
|
||||
@ -265,11 +278,13 @@ class UserFlagManager(models.Manager):
|
||||
mail_managers('Comment flagged', message, fail_silently=True)
|
||||
f.save()
|
||||
|
||||
|
||||
class UserFlag(models.Model):
|
||||
user = models.ForeignKey(User)
|
||||
comment = models.ForeignKey(Comment)
|
||||
flag_date = models.DateTimeField(_('flag date'), auto_now_add=True)
|
||||
objects = UserFlagManager()
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('user flag')
|
||||
verbose_name_plural = _('user flags')
|
||||
@ -278,10 +293,12 @@ class UserFlag(models.Model):
|
||||
def __unicode__(self):
|
||||
return _("Flag by %r") % self.user
|
||||
|
||||
|
||||
class ModeratorDeletion(models.Model):
|
||||
user = models.ForeignKey(User, verbose_name='moderator')
|
||||
comment = models.ForeignKey(Comment)
|
||||
deletion_date = models.DateTimeField(_('deletion date'), auto_now_add=True)
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('moderator deletion')
|
||||
verbose_name_plural = _('moderator deletions')
|
||||
|
@ -105,7 +105,7 @@ class EasyInstance(object):
|
||||
return self.instance._get_pk_val()
|
||||
|
||||
def url(self):
|
||||
return '%s%s/%s/objects/%s/' % (self.model.site.root_url, self.model.model._meta.app_label, self.model.model._meta.module_name, iri_to_uri(self.pk()))
|
||||
return mark_safe('%s%s/%s/objects/%s/' % (self.model.site.root_url, self.model.model._meta.app_label, self.model.model._meta.module_name, iri_to_uri(self.pk())))
|
||||
|
||||
def fields(self):
|
||||
"""
|
||||
|
@ -20,7 +20,7 @@ class ARProvinceSelect(Select):
|
||||
|
||||
class ARPostalCodeField(RegexField):
|
||||
"""
|
||||
A field that accepts a `classic´ NNNN Postal Code or a CPA.
|
||||
A field that accepts a 'classic' NNNN Postal Code or a CPA.
|
||||
|
||||
See http://www.correoargentino.com.ar/consulta_cpa/home.php
|
||||
"""
|
||||
@ -44,7 +44,7 @@ class ARPostalCodeField(RegexField):
|
||||
|
||||
class ARDNIField(CharField):
|
||||
"""
|
||||
A field that validates `Documento Nacional de Identidad´ (DNI) numbers.
|
||||
A field that validates 'Documento Nacional de Identidad' (DNI) numbers.
|
||||
"""
|
||||
default_error_messages = {
|
||||
'invalid': ugettext("This field requires only numbers."),
|
||||
@ -73,7 +73,7 @@ class ARDNIField(CharField):
|
||||
|
||||
class ARCUITField(RegexField):
|
||||
"""
|
||||
This field validates a CUIT (Código Único de Identificación Tributaria). A
|
||||
This field validates a CUIT (Código Único de Identificación Tributaria). A
|
||||
CUIT is of the form XX-XXXXXXXX-V. The last digit is a check digit.
|
||||
"""
|
||||
default_error_messages = {
|
||||
|
@ -55,7 +55,7 @@ NORTHERN_IRELAND_REGION_CHOICES = (
|
||||
("County Antrim", _("County Antrim")),
|
||||
("County Armagh", _("County Armagh")),
|
||||
("County Down", _("County Down")),
|
||||
("County Fermanagh", _("County Down")),
|
||||
("County Fermanagh", _("County Fermanagh")),
|
||||
("County Londonderry", _("County Londonderry")),
|
||||
("County Tyrone", _("County Tyrone")),
|
||||
)
|
||||
|
@ -6,7 +6,7 @@ from django.utils.encoding import smart_unicode, iri_to_uri
|
||||
from django.conf import settings
|
||||
|
||||
def add_domain(domain, url):
|
||||
if not url.startswith('http://'):
|
||||
if not (url.startswith('http://') or url.startswith('https://')):
|
||||
# 'url' must already be ASCII and URL-quoted, so no need for encoding
|
||||
# conversions here.
|
||||
url = iri_to_uri(u'http://%s%s' % (domain, url))
|
||||
@ -82,7 +82,8 @@ class Feed(object):
|
||||
link = link,
|
||||
description = self.__get_dynamic_attr('description', obj),
|
||||
language = settings.LANGUAGE_CODE.decode(),
|
||||
feed_url = add_domain(current_site, self.__get_dynamic_attr('feed_url', obj)),
|
||||
feed_url = add_domain(current_site.domain,
|
||||
self.__get_dynamic_attr('feed_url', obj)),
|
||||
author_name = self.__get_dynamic_attr('author_name', obj),
|
||||
author_link = self.__get_dynamic_attr('author_link', obj),
|
||||
author_email = self.__get_dynamic_attr('author_email', obj),
|
||||
|
@ -111,13 +111,13 @@ class BaseHandler(object):
|
||||
except SystemExit:
|
||||
pass # See http://code.djangoproject.com/ticket/1023
|
||||
except: # Handle everything else, including SuspiciousOperation, etc.
|
||||
# Get the exception info now, in case another exception is thrown later.
|
||||
exc_info = sys.exc_info()
|
||||
receivers = dispatcher.send(signal=signals.got_request_exception, request=request)
|
||||
if settings.DEBUG:
|
||||
from django.views import debug
|
||||
return debug.technical_500_response(request, *sys.exc_info())
|
||||
return debug.technical_500_response(request, *exc_info)
|
||||
else:
|
||||
# Get the exception info now, in case another exception is thrown later.
|
||||
exc_info = sys.exc_info()
|
||||
receivers = dispatcher.send(signal=signals.got_request_exception, request=request)
|
||||
# When DEBUG is False, send an error message to the admins.
|
||||
subject = 'Error (%s IP): %s' % ((request.META.get('REMOTE_ADDR') in settings.INTERNAL_IPS and 'internal' or 'EXTERNAL'), request.path)
|
||||
try:
|
||||
|
@ -59,7 +59,7 @@ class Command(BaseCommand):
|
||||
else:
|
||||
formats = []
|
||||
|
||||
if verbosity > 2:
|
||||
if verbosity >= 2:
|
||||
if formats:
|
||||
print "Loading '%s' fixtures..." % fixture_name
|
||||
else:
|
||||
@ -109,7 +109,7 @@ class Command(BaseCommand):
|
||||
return
|
||||
fixture.close()
|
||||
except:
|
||||
if verbosity > 2:
|
||||
if verbosity >= 2:
|
||||
print "No %s fixture '%s' in %s." % \
|
||||
(format, fixture_name, humanize(fixture_dir))
|
||||
|
||||
@ -125,7 +125,7 @@ class Command(BaseCommand):
|
||||
transaction.leave_transaction_management()
|
||||
|
||||
if count[0] == 0:
|
||||
if verbosity > 2:
|
||||
if verbosity >= 2:
|
||||
print "No fixtures found."
|
||||
else:
|
||||
if verbosity > 0:
|
||||
|
@ -209,7 +209,8 @@ class Model(object):
|
||||
_prepare = classmethod(_prepare)
|
||||
|
||||
def save(self, raw=False):
|
||||
dispatcher.send(signal=signals.pre_save, sender=self.__class__, instance=self)
|
||||
dispatcher.send(signal=signals.pre_save, sender=self.__class__,
|
||||
instance=self, raw=raw)
|
||||
|
||||
non_pks = [f for f in self._meta.fields if not f.primary_key]
|
||||
|
||||
@ -255,7 +256,7 @@ class Model(object):
|
||||
|
||||
# Run any post-save hooks.
|
||||
dispatcher.send(signal=signals.post_save, sender=self.__class__,
|
||||
instance=self, created=(not record_exists))
|
||||
instance=self, created=(not record_exists), raw=raw)
|
||||
|
||||
save.alters_data = True
|
||||
|
||||
|
@ -22,12 +22,12 @@ class GZipMiddleware(object):
|
||||
if response.has_header('Content-Encoding'):
|
||||
return response
|
||||
|
||||
# Older versions of IE have issues with gzipped javascript.
|
||||
# See http://code.djangoproject.com/ticket/2449
|
||||
is_ie = "msie" in request.META.get('HTTP_USER_AGENT', '').lower()
|
||||
is_js = "javascript" in response.get('Content-Type', '').lower()
|
||||
if is_ie and is_js:
|
||||
return response
|
||||
# Older versions of IE have issues with gzipped pages containing either
|
||||
# Javascript and PDF.
|
||||
if "msie" in request.META.get('HTTP_USER_AGENT', '').lower():
|
||||
ctype = response.get('Content-Type', '').lower()
|
||||
if "javascript" in ctype or ctype == "application/pdf":
|
||||
return response
|
||||
|
||||
ae = request.META.get('HTTP_ACCEPT_ENCODING', '')
|
||||
if not re_accepts_gzip.search(ae):
|
||||
|
@ -228,7 +228,7 @@ class ModelFormMetaclass(type):
|
||||
opts = ModelFormOptions(attrs.get('Meta', None))
|
||||
attrs['_meta'] = opts
|
||||
|
||||
# Don't allow more than one Meta model defenition in bases. The fields
|
||||
# Don't allow more than one Meta model definition in bases. The fields
|
||||
# would be generated correctly, but the save method won't deal with
|
||||
# more than one object.
|
||||
base_models = []
|
||||
|
@ -426,7 +426,7 @@ class MultiWidget(Widget):
|
||||
if id_:
|
||||
final_attrs = dict(final_attrs, id='%s_%s' % (id_, i))
|
||||
output.append(widget.render(name + '_%s' % i, widget_value, final_attrs))
|
||||
return self.format_output(output)
|
||||
return mark_safe(self.format_output(output))
|
||||
|
||||
def id_for_label(self, id_):
|
||||
# See the comment for RadioSelect.id_for_label()
|
||||
|
@ -289,6 +289,9 @@ class Parser(object):
|
||||
return NodeList()
|
||||
|
||||
def extend_nodelist(self, nodelist, node, token):
|
||||
if (node.must_be_first and nodelist and
|
||||
(not isinstance(nodelist[0], TextNode) or len(nodelist) > 2)):
|
||||
raise TemplateSyntaxError("%r must be the first tag in the template." % node)
|
||||
nodelist.append(node)
|
||||
|
||||
def enter_command(self, command, token):
|
||||
@ -708,6 +711,10 @@ class Variable(object):
|
||||
return current
|
||||
|
||||
class Node(object):
|
||||
# Set this to True for nodes that must be first in the template (although
|
||||
# they can be preceded by text nodes.
|
||||
must_be_first = False
|
||||
|
||||
def render(self, context):
|
||||
"Return the node rendered as a string"
|
||||
pass
|
||||
|
@ -343,7 +343,7 @@ def force_escape(value):
|
||||
"""
|
||||
from django.utils.html import escape
|
||||
return mark_safe(escape(value))
|
||||
escape = stringfilter(escape)
|
||||
force_escape = stringfilter(force_escape)
|
||||
force_escape.is_safe = True
|
||||
|
||||
def linebreaks(value, autoescape=None):
|
||||
|
@ -1,5 +1,5 @@
|
||||
from django.template import TemplateSyntaxError, TemplateDoesNotExist, Variable
|
||||
from django.template import Library, Node
|
||||
from django.template import Library, Node, TextNode
|
||||
from django.template.loader import get_template, get_template_from_string, find_template_source
|
||||
from django.conf import settings
|
||||
from django.utils.safestring import mark_safe
|
||||
@ -37,11 +37,18 @@ class BlockNode(Node):
|
||||
self.parent = BlockNode(self.name, nodelist)
|
||||
|
||||
class ExtendsNode(Node):
|
||||
must_be_first = True
|
||||
|
||||
def __init__(self, nodelist, parent_name, parent_name_expr, template_dirs=None):
|
||||
self.nodelist = nodelist
|
||||
self.parent_name, self.parent_name_expr = parent_name, parent_name_expr
|
||||
self.template_dirs = template_dirs
|
||||
|
||||
def __repr__(self):
|
||||
if self.parent_name_expr:
|
||||
return "<ExtendsNode: extends %s>" % self.parent_name_expr.token
|
||||
return '<ExtendsNode: extends "%s">' % self.parent_name
|
||||
|
||||
def get_parent(self, context):
|
||||
if self.parent_name_expr:
|
||||
self.parent_name = self.parent_name_expr.resolve(context)
|
||||
@ -49,7 +56,7 @@ class ExtendsNode(Node):
|
||||
if not parent:
|
||||
error_msg = "Invalid template name in 'extends' tag: %r." % parent
|
||||
if self.parent_name_expr:
|
||||
error_msg += " Got this from the %r variable." % self.parent_name_expr #TODO nice repr.
|
||||
error_msg += " Got this from the '%s' variable." % self.parent_name_expr.token
|
||||
raise TemplateSyntaxError, error_msg
|
||||
if hasattr(parent, 'render'):
|
||||
return parent # parent is a Template object
|
||||
@ -62,7 +69,14 @@ class ExtendsNode(Node):
|
||||
|
||||
def render(self, context):
|
||||
compiled_parent = self.get_parent(context)
|
||||
parent_is_child = isinstance(compiled_parent.nodelist[0], ExtendsNode)
|
||||
if len(compiled_parent.nodelist) > 1:
|
||||
n0, n1 = compiled_parent.nodelist[:2]
|
||||
else:
|
||||
n0, n1 = compiled_parent.nodelist[0], None
|
||||
parent_is_child = (isinstance(n0, ExtendsNode) or
|
||||
(isinstance(n0, TextNode) and isinstance(n1, ExtendsNode)))
|
||||
if parent_is_child:
|
||||
extend_node = int(not isinstance(n0, ExtendsNode))
|
||||
parent_blocks = dict([(n.name, n) for n in compiled_parent.nodelist.get_nodes_by_type(BlockNode)])
|
||||
for block_node in self.nodelist.get_nodes_by_type(BlockNode):
|
||||
# Check for a BlockNode with this node's name, and replace it if found.
|
||||
@ -74,7 +88,7 @@ class ExtendsNode(Node):
|
||||
# add this BlockNode to the parent's ExtendsNode nodelist, so
|
||||
# it'll be checked when the parent node's render() is called.
|
||||
if parent_is_child:
|
||||
compiled_parent.nodelist[0].nodelist.append(block_node)
|
||||
compiled_parent.nodelist[extend_node].nodelist.append(block_node)
|
||||
else:
|
||||
# Keep any existing parents and add a new one. Used by BlockNode.
|
||||
parent_block.parent = block_node.parent
|
||||
|
@ -262,7 +262,7 @@ class Client:
|
||||
self.cookies[settings.SESSION_COOKIE_NAME]['expires'] = None
|
||||
|
||||
# Save the session values
|
||||
request.session.save()
|
||||
request.session.save()
|
||||
|
||||
return True
|
||||
else:
|
||||
@ -274,5 +274,5 @@ class Client:
|
||||
Causes the authenticated user to be logged out.
|
||||
"""
|
||||
session = __import__(settings.SESSION_ENGINE, {}, {}, ['']).SessionStore()
|
||||
session.delete(session_key=self.cookies['sessionid'].value)
|
||||
session.delete(session_key=self.cookies[settings.SESSION_COOKIE_NAME].value)
|
||||
self.cookies = SimpleCookie()
|
||||
|
@ -72,6 +72,8 @@ class TestCase(unittest.TestCase):
|
||||
self.client = Client()
|
||||
try:
|
||||
self._pre_setup()
|
||||
except (KeyboardInterrupt, SystemExit):
|
||||
raise
|
||||
except Exception:
|
||||
import sys
|
||||
result.addError(self, sys.exc_info())
|
||||
@ -108,7 +110,7 @@ class TestCase(unittest.TestCase):
|
||||
|
||||
def assertContains(self, response, text, count=None, status_code=200):
|
||||
"""
|
||||
Asserts that a response indicates that a page was retreived
|
||||
Asserts that a response indicates that a page was retrieved
|
||||
successfully, (i.e., the HTTP status code was as expected), and that
|
||||
``text`` occurs ``count`` times in the content of the response.
|
||||
If ``count`` is None, the count doesn't matter - the assertion is true
|
||||
|
@ -2,6 +2,9 @@ class MergeDict(object):
|
||||
"""
|
||||
A simple class for creating new "virtual" dictionaries that actually look
|
||||
up values in more than one dictionary, passed in the constructor.
|
||||
|
||||
If a key appears in more than one of the passed in dictionaries, only the
|
||||
first occurrence will be used.
|
||||
"""
|
||||
def __init__(self, *dicts):
|
||||
self.dicts = dicts
|
||||
@ -25,11 +28,9 @@ class MergeDict(object):
|
||||
|
||||
def getlist(self, key):
|
||||
for dict_ in self.dicts:
|
||||
try:
|
||||
if key in dict_.keys():
|
||||
return dict_.getlist(key)
|
||||
except KeyError:
|
||||
pass
|
||||
raise KeyError
|
||||
return []
|
||||
|
||||
def items(self):
|
||||
item_list = []
|
||||
|
@ -98,5 +98,5 @@ def iri_to_uri(iri):
|
||||
# section 3.1 of RFC 3987.
|
||||
if iri is None:
|
||||
return iri
|
||||
return urllib.quote(smart_str(iri), safe='/#%[]=:;$&()+,!?')
|
||||
return urllib.quote(smart_str(iri), safe='/#%[]=:;$&()+,!?*')
|
||||
|
||||
|
@ -53,7 +53,7 @@ class SyndicationFeed(object):
|
||||
'title': to_unicode(title),
|
||||
'link': iri_to_uri(link),
|
||||
'description': to_unicode(description),
|
||||
'language': force_unicode(language),
|
||||
'language': to_unicode(language),
|
||||
'author_email': to_unicode(author_email),
|
||||
'author_name': to_unicode(author_name),
|
||||
'author_link': iri_to_uri(author_link),
|
||||
|
@ -102,18 +102,23 @@ def urlize(text, trim_url_limit=None, nofollow=False, autoescape=False):
|
||||
if middle.startswith('www.') or ('@' not in middle and not middle.startswith('http://') and \
|
||||
len(middle) > 0 and middle[0] in string.ascii_letters + string.digits and \
|
||||
(middle.endswith('.org') or middle.endswith('.net') or middle.endswith('.com'))):
|
||||
middle = '<a href="http://%s"%s>%s</a>' % (
|
||||
urlquote(middle, safe='/&=:;#?+'), nofollow_attr,
|
||||
trim_url(middle))
|
||||
middle = 'http://%s' % middle
|
||||
if middle.startswith('http://') or middle.startswith('https://'):
|
||||
middle = '<a href="%s"%s>%s</a>' % (
|
||||
urlquote(middle, safe='/&=:;#?+'), nofollow_attr,
|
||||
trim_url(middle))
|
||||
if '@' in middle and not middle.startswith('www.') and \
|
||||
not ':' in middle and simple_email_re.match(middle):
|
||||
url = urlquote(middle, safe='/&=:;#?+*')
|
||||
if autoescape and not safe_input:
|
||||
url = escape(url)
|
||||
trimmed_url = trim_url(middle)
|
||||
middle = '<a href="%s"%s>%s</a>' % (url, nofollow_attr,
|
||||
trimmed_url)
|
||||
elif '@' in middle and not middle.startswith('www.') and \
|
||||
not ':' in middle and simple_email_re.match(middle):
|
||||
if autoescape:
|
||||
middle = conditional_escape(middle)
|
||||
middle = '<a href="mailto:%s">%s</a>' % (middle, middle)
|
||||
if lead + middle + trail != word:
|
||||
words[i] = lead + middle + trail
|
||||
if autoescape and not safe_input:
|
||||
lead, trail = escape(lead), escape(trail)
|
||||
words[i] = mark_safe('%s%s%s' % (lead, middle, trail))
|
||||
elif autoescape and not safe_input:
|
||||
words[i] = escape(word)
|
||||
elif safe_input:
|
||||
|
@ -73,6 +73,12 @@ def technical_500_response(request, exc_type, exc_value, tb):
|
||||
template_info = None
|
||||
template_does_not_exist = False
|
||||
loader_debug_info = None
|
||||
|
||||
# Handle deprecated string exceptions
|
||||
if isinstance(exc_type, basestring):
|
||||
exc_value = Exception('Deprecated String Exception: %r' % exc_type)
|
||||
exc_type = type(exc_value)
|
||||
|
||||
if issubclass(exc_type, TemplateDoesNotExist):
|
||||
from django.template.loader import template_source_loaders
|
||||
template_does_not_exist = True
|
||||
@ -192,9 +198,11 @@ def _get_lines_from_file(filename, lineno, context_lines, loader=None, module_na
|
||||
Returns (pre_context_lineno, pre_context, context_line, post_context).
|
||||
"""
|
||||
source = None
|
||||
if loader is not None:
|
||||
source = loader.get_source(module_name).splitlines()
|
||||
else:
|
||||
if loader is not None and hasattr(loader, "get_source"):
|
||||
source = loader.get_source(module_name)
|
||||
if source is not None:
|
||||
source = source.splitlines()
|
||||
if source is None:
|
||||
try:
|
||||
f = open(filename)
|
||||
try:
|
||||
@ -431,11 +439,11 @@ TECHNICAL_500_TEMPLATE = """
|
||||
{% if frame.context_line %}
|
||||
<div class="context" id="c{{ frame.id }}">
|
||||
{% if frame.pre_context %}
|
||||
<ol start="{{ frame.pre_context_lineno }}" class="pre-context" id="pre{{ frame.id }}">{% for line in frame.pre_context %}<li onclick="toggle('pre{{ frame.id }}', 'post{{ frame.id }}')">{{ line|escape }}</li>{% endfor %}</ol>
|
||||
<ol start="{{ frame.pre_context_lineno }}" class="pre-context" id="pre{{ frame.id }}">{% for line in frame.pre_context %}{% if line %}<li onclick="toggle('pre{{ frame.id }}', 'post{{ frame.id }}')">{{ line|escape }}</li>{% endif %}{% endfor %}</ol>
|
||||
{% endif %}
|
||||
<ol start="{{ frame.lineno }}" class="context-line"><li onclick="toggle('pre{{ frame.id }}', 'post{{ frame.id }}')">{{ frame.context_line|escape }} <span>...</span></li></ol>
|
||||
{% if frame.post_context %}
|
||||
<ol start='{{ frame.lineno|add:"1" }}' class="post-context" id="post{{ frame.id }}">{% for line in frame.post_context %}<li onclick="toggle('pre{{ frame.id }}', 'post{{ frame.id }}')">{{ line|escape }}</li>{% endfor %}</ol>
|
||||
<ol start='{{ frame.lineno|add:"1" }}' class="post-context" id="post{{ frame.id }}">{% for line in frame.post_context %}{% if line %}<li onclick="toggle('pre{{ frame.id }}', 'post{{ frame.id }}')">{{ line|escape }}</li>{% endif %}{% endfor %}</ol>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
@ -292,6 +292,14 @@ translation string. Example::
|
||||
In this case, both the tag and the filter will see the already-translated
|
||||
string, so they don't need to be aware of translations.
|
||||
|
||||
.. note::
|
||||
In this example, the translation infrastructure will be passed the string
|
||||
``"yes,no"``, not the individual strings ``"yes"`` and ``"no"``. The
|
||||
translated string will need to contain the comma so that the filter
|
||||
parsing code knows how to split up the arguments. For example, a German
|
||||
translator might translate the string ``"yes,no"`` as ``"ja,nein"``
|
||||
(keeping the comma intact).
|
||||
|
||||
.. _Django templates: ../templates_python/
|
||||
|
||||
Working with lazy translation objects
|
||||
|
@ -113,10 +113,23 @@ postal code or a CPA_.
|
||||
|
||||
.. _CPA: http://www.correoargentino.com.ar/consulta_cpa/home.php
|
||||
|
||||
ARDNIField
|
||||
----------
|
||||
|
||||
A form field that validates input as a Documento Nacional de Identidad (DNI)
|
||||
number.
|
||||
|
||||
ARCUITField
|
||||
-----------
|
||||
|
||||
A form field that validates input as a Código Único de Identificación
|
||||
Tributaria (CUIT) number.
|
||||
|
||||
ARProvinceSelect
|
||||
----------------
|
||||
|
||||
A ``Select`` widget that uses a list of Argentina's provinces as its choices.
|
||||
A ``Select`` widget that uses a list of Argentina's provinces and autonomous
|
||||
cities as its choices.
|
||||
|
||||
Australia (``django.contrib.localflavor.au``)
|
||||
=============================================
|
||||
@ -610,7 +623,7 @@ UKNationSelect
|
||||
|
||||
A ``Select`` widget that uses a list of UK nations as its choices.
|
||||
|
||||
United States of America (``django.contrib.localflavor.us``)
|
||||
United States of America (``django.contrib.localflavor.us``)
|
||||
============================================================
|
||||
|
||||
USPhoneNumberField
|
||||
@ -635,7 +648,7 @@ A valid SSN must obey the following rules:
|
||||
USStateField
|
||||
------------
|
||||
|
||||
A form field that validates input as a U.S. state name or abbreviation. It
|
||||
A form field that validates input as a U.S. state name or abbreviation. It
|
||||
normalizes the input to the standard two-letter postal service abbreviation
|
||||
for the given state.
|
||||
|
||||
|
@ -17,7 +17,7 @@ class from a Django model.
|
||||
For example::
|
||||
|
||||
>>> from django.newforms import ModelForm
|
||||
|
||||
|
||||
# Create the form class.
|
||||
>>> class ArticleForm(ModelForm):
|
||||
... class Meta:
|
||||
@ -113,7 +113,7 @@ In addition, each generated form field has attributes set as follows:
|
||||
``default`` value will be initially selected instead).
|
||||
|
||||
Finally, note that you can override the form field used for a given model
|
||||
field. See "Overriding the default field types" below.
|
||||
field. See `Overriding the default field types`_ below.
|
||||
|
||||
A full example
|
||||
--------------
|
||||
@ -278,7 +278,7 @@ model fields:
|
||||
To avoid this failure, you must instantiate your model with initial values
|
||||
for the missing, but required fields, or use ``save(commit=False)`` and
|
||||
manually set any extra required fields::
|
||||
|
||||
|
||||
instance = Instance(required_field='value')
|
||||
form = InstanceForm(request.POST, instance=instance)
|
||||
new_instance = form.save()
|
||||
@ -295,7 +295,7 @@ model fields:
|
||||
Overriding the default field types
|
||||
----------------------------------
|
||||
|
||||
The default field types, as described in the "Field types" table above, are
|
||||
The default field types, as described in the `Field types`_ table above, are
|
||||
sensible defaults. If you have a ``DateField`` in your model, chances are you'd
|
||||
want that to be represented as a ``DateField`` in your form. But
|
||||
``ModelForm`` gives you the flexibility of changing the form field type
|
||||
@ -311,3 +311,12 @@ field, you could do the following::
|
||||
...
|
||||
... class Meta:
|
||||
... model = Article
|
||||
|
||||
If you want to override a field's default widget, then specify the ``widget``
|
||||
parameter when declaring the form field::
|
||||
|
||||
>>> class ArticleForm(ModelForm):
|
||||
... pub_date = DateField(widget=MyDateWidget())
|
||||
...
|
||||
... class Meta:
|
||||
... model = Article
|
||||
|
@ -575,6 +575,10 @@ Three things to note about 404 views:
|
||||
to the template: ``request_path``, which is the URL that resulted
|
||||
in the 404.
|
||||
|
||||
* The 404 view is passed a ``RequestContext`` and will have access to
|
||||
variables supplied by your ``TEMPLATE_CONTEXT_PROCESSORS`` (e.g.
|
||||
``MEDIA_URL``).
|
||||
|
||||
* If ``DEBUG`` is set to ``True`` (in your settings module), then your 404
|
||||
view will never be used, and the traceback will be displayed instead.
|
||||
|
||||
@ -587,8 +591,9 @@ the view ``django.views.defaults.server_error``, which loads and renders the
|
||||
template ``500.html``.
|
||||
|
||||
This means you need to define a ``500.html`` template in your root template
|
||||
directory. This template will be used for all server errors. The
|
||||
default 500 view passes no variables to this template.
|
||||
directory. This template will be used for all server errors. The default 500
|
||||
view passes no variables to this template and is rendered with an empty
|
||||
``Context`` to lessen the chance of additional errors.
|
||||
|
||||
This ``server_error`` view should suffice for 99% of Web applications, but if
|
||||
you want to override the view, you can specify ``handler500`` in your
|
||||
|
@ -22,16 +22,29 @@ Required arguments
|
||||
Optional arguments
|
||||
------------------
|
||||
|
||||
``context``
|
||||
``dictionary``
|
||||
A dictionary of values to add to the template context. By default, this
|
||||
is an empty dictionary. If a value in the dictionary is callable, the
|
||||
view will call it just before rendering the template.
|
||||
|
||||
``context_instance``
|
||||
The context instance to render the template with. By default, the template
|
||||
will be rendered with a ``Context`` instance (filled with values from
|
||||
``dictionary``). If you need to use `context processors`_, you will want to
|
||||
render the template with a ``RequestContext`` instance instead. Your code
|
||||
might look something like this::
|
||||
|
||||
return render_to_response('my_template.html',
|
||||
my_data_dictionary,
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
``mimetype``
|
||||
**New in Django development version:** The MIME type to use for the
|
||||
resulting document. Defaults to the value of the ``DEFAULT_CONTENT_TYPE``
|
||||
setting.
|
||||
|
||||
.. _`context processors`: ../templates_python/#subclassing-context-requestcontext
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
@ -57,8 +70,6 @@ This example is equivalent to::
|
||||
r = HttpResponse(t.render(c),
|
||||
mimetype="application/xhtml+xml")
|
||||
|
||||
.. _an HttpResponse object: ../request_response/#httpresponse-objects
|
||||
|
||||
``get_object_or_404``
|
||||
=====================
|
||||
|
||||
|
@ -13,8 +13,16 @@ class Person(models.Model):
|
||||
return u"%s %s" % (self.first_name, self.last_name)
|
||||
|
||||
|
||||
def pre_save_nokwargs_test(sender, instance):
|
||||
print 'pre_save_nokwargs signal'
|
||||
|
||||
def post_save_nokwargs_test(sender, instance):
|
||||
print 'post_save_nokwargs signal'
|
||||
|
||||
def pre_save_test(sender, instance, **kwargs):
|
||||
print 'pre_save signal,', instance
|
||||
if kwargs.get('raw'):
|
||||
print 'Is raw'
|
||||
|
||||
def post_save_test(sender, instance, **kwargs):
|
||||
print 'post_save signal,', instance
|
||||
@ -23,16 +31,20 @@ def post_save_test(sender, instance, **kwargs):
|
||||
print 'Is created'
|
||||
else:
|
||||
print 'Is updated'
|
||||
if kwargs.get('raw'):
|
||||
print 'Is raw'
|
||||
|
||||
def pre_delete_test(sender, instance, **kwargs):
|
||||
print 'pre_delete signal,', instance
|
||||
print 'instance.id is not None: %s' % (instance.id != None)
|
||||
print 'instance.id is not None: %s' % (instance.id != None)
|
||||
|
||||
def post_delete_test(sender, instance, **kwargs):
|
||||
print 'post_delete signal,', instance
|
||||
print 'instance.id is None: %s' % (instance.id == None)
|
||||
print 'instance.id is None: %s' % (instance.id == None)
|
||||
|
||||
__test__ = {'API_TESTS':"""
|
||||
>>> dispatcher.connect(pre_save_nokwargs_test, signal=models.signals.pre_save)
|
||||
>>> dispatcher.connect(post_save_nokwargs_test, signal=models.signals.post_save)
|
||||
>>> dispatcher.connect(pre_save_test, signal=models.signals.pre_save)
|
||||
>>> dispatcher.connect(post_save_test, signal=models.signals.post_save)
|
||||
>>> dispatcher.connect(pre_delete_test, signal=models.signals.pre_delete)
|
||||
@ -40,16 +52,29 @@ __test__ = {'API_TESTS':"""
|
||||
|
||||
>>> p1 = Person(first_name='John', last_name='Smith')
|
||||
>>> p1.save()
|
||||
pre_save_nokwargs signal
|
||||
pre_save signal, John Smith
|
||||
post_save_nokwargs signal
|
||||
post_save signal, John Smith
|
||||
Is created
|
||||
|
||||
>>> p1.first_name = 'Tom'
|
||||
>>> p1.save()
|
||||
pre_save_nokwargs signal
|
||||
pre_save signal, Tom Smith
|
||||
post_save_nokwargs signal
|
||||
post_save signal, Tom Smith
|
||||
Is updated
|
||||
|
||||
>>> p1.save(raw=True)
|
||||
pre_save_nokwargs signal
|
||||
pre_save signal, Tom Smith
|
||||
Is raw
|
||||
post_save_nokwargs signal
|
||||
post_save signal, Tom Smith
|
||||
Is updated
|
||||
Is raw
|
||||
|
||||
>>> p1.delete()
|
||||
pre_delete signal, Tom Smith
|
||||
instance.id is not None: True
|
||||
@ -59,13 +84,17 @@ instance.id is None: False
|
||||
>>> p2 = Person(first_name='James', last_name='Jones')
|
||||
>>> p2.id = 99999
|
||||
>>> p2.save()
|
||||
pre_save_nokwargs signal
|
||||
pre_save signal, James Jones
|
||||
post_save_nokwargs signal
|
||||
post_save signal, James Jones
|
||||
Is created
|
||||
|
||||
>>> p2.id = 99998
|
||||
>>> p2.save()
|
||||
pre_save_nokwargs signal
|
||||
pre_save signal, James Jones
|
||||
post_save_nokwargs signal
|
||||
post_save signal, James Jones
|
||||
Is created
|
||||
|
||||
@ -78,6 +107,8 @@ instance.id is None: False
|
||||
>>> Person.objects.all()
|
||||
[<Person: James Jones>]
|
||||
|
||||
>>> dispatcher.disconnect(pre_save_nokwargs_test, signal=models.signals.pre_save)
|
||||
>>> dispatcher.disconnect(post_save_nokwargs_test, signal=models.signals.post_save)
|
||||
>>> dispatcher.disconnect(post_delete_test, signal=models.signals.post_delete)
|
||||
>>> dispatcher.disconnect(pre_delete_test, signal=models.signals.pre_delete)
|
||||
>>> dispatcher.disconnect(post_save_test, signal=models.signals.post_save)
|
||||
|
@ -20,6 +20,19 @@
|
||||
>>> md2['chris']
|
||||
'cool'
|
||||
|
||||
MergeDict can merge MultiValueDicts
|
||||
>>> multi1 = MultiValueDict({'key1': ['value1'], 'key2': ['value2', 'value3']})
|
||||
>>> multi2 = MultiValueDict({'key2': ['value4'], 'key4': ['value5', 'value6']})
|
||||
>>> mm = MergeDict(multi1, multi2)
|
||||
|
||||
# Although 'key2' appears in both dictionaries, only the first value is used.
|
||||
>>> mm.getlist('key2')
|
||||
['value2', 'value3']
|
||||
>>> mm.getlist('key4')
|
||||
['value5', 'value6']
|
||||
>>> mm.getlist('undefined')
|
||||
[]
|
||||
|
||||
### MultiValueDict ##########################################################
|
||||
|
||||
>>> d = MultiValueDict({'name': ['Adrian', 'Simon'], 'position': ['Developer']})
|
||||
|
@ -98,8 +98,8 @@ def get_filter_tests():
|
||||
'filter-upper01': ('{% autoescape off %}{{ a|upper }} {{ b|upper }}{% endautoescape %}', {"a": "a & b", "b": mark_safe("a & b")}, u"A & B A & B"),
|
||||
'filter-upper02': ('{{ a|upper }} {{ b|upper }}', {"a": "a & b", "b": mark_safe("a & b")}, u"A & B A &AMP; B"),
|
||||
|
||||
'filter-urlize01': ('{% autoescape off %}{{ a|urlize }} {{ b|urlize }}{% endautoescape %}', {"a": "http://example.com/x=&y=", "b": mark_safe("http://example.com?x=&y=")}, u'<a href="http://example.com/x=&y=" rel="nofollow">http://example.com/x=&y=</a> <a href="http://example.com?x=&y=" rel="nofollow">http://example.com?x=&y=</a>'),
|
||||
'filter-urlize02': ('{{ a|urlize }} {{ b|urlize }}', {"a": "http://example.com/x=&y=", "b": mark_safe("http://example.com?x=&y=")}, u'<a href="http://example.com/x=&y=" rel="nofollow">http://example.com/x=&y=</a> <a href="http://example.com?x=&y=" rel="nofollow">http://example.com?x=&y=</a>'),
|
||||
'filter-urlize01': ('{% autoescape off %}{{ a|urlize }} {{ b|urlize }}{% endautoescape %}', {"a": "http://example.com/?x=&y=", "b": mark_safe("http://example.com?x=&y=")}, u'<a href="http://example.com/?x=&y=" rel="nofollow">http://example.com/?x=&y=</a> <a href="http://example.com?x=&y=" rel="nofollow">http://example.com?x=&y=</a>'),
|
||||
'filter-urlize02': ('{{ a|urlize }} {{ b|urlize }}', {"a": "http://example.com/?x=&y=", "b": mark_safe("http://example.com?x=&y=")}, u'<a href="http://example.com/?x=&y=" rel="nofollow">http://example.com/?x=&y=</a> <a href="http://example.com?x=&y=" rel="nofollow">http://example.com?x=&y=</a>'),
|
||||
'filter-urlize03': ('{% autoescape off %}{{ a|urlize }}{% endautoescape %}', {"a": mark_safe("a & b")}, 'a & b'),
|
||||
'filter-urlize04': ('{{ a|urlize }}', {"a": mark_safe("a & b")}, 'a & b'),
|
||||
|
||||
@ -108,8 +108,12 @@ def get_filter_tests():
|
||||
'filter-urlize05': ('{% autoescape off %}{{ a|urlize }}{% endautoescape %}', {"a": "<script>alert('foo')</script>"}, "<script>alert('foo')</script>"),
|
||||
'filter-urlize06': ('{{ a|urlize }}', {"a": "<script>alert('foo')</script>"}, '<script>alert('foo')</script>'),
|
||||
|
||||
'filter-urlizetrunc01': ('{% autoescape off %}{{ a|urlizetrunc:"8" }} {{ b|urlizetrunc:"8" }}{% endautoescape %}', {"a": '"Unsafe" http://example.com/x=&y=', "b": mark_safe('"Safe" http://example.com?x=&y=')}, u'"Unsafe" <a href="http://example.com/x=&y=" rel="nofollow">http:...</a> "Safe" <a href="http://example.com?x=&y=" rel="nofollow">http:...</a>'),
|
||||
'filter-urlizetrunc02': ('{{ a|urlizetrunc:"8" }} {{ b|urlizetrunc:"8" }}', {"a": '"Unsafe" http://example.com/x=&y=', "b": mark_safe('"Safe" http://example.com?x=&y=')}, u'"Unsafe" <a href="http://example.com/x=&y=" rel="nofollow">http:...</a> "Safe" <a href="http://example.com?x=&y=" rel="nofollow">http:...</a>'),
|
||||
# mailto: testing for urlize
|
||||
'filter-urlize07': ('{{ a|urlize }}', {"a": "Email me at me@example.com"}, 'Email me at <a href="mailto:me@example.com">me@example.com</a>'),
|
||||
'filter-urlize08': ('{{ a|urlize }}', {"a": "Email me at <me@example.com>"}, 'Email me at <<a href="mailto:me@example.com">me@example.com</a>>'),
|
||||
|
||||
'filter-urlizetrunc01': ('{% autoescape off %}{{ a|urlizetrunc:"8" }} {{ b|urlizetrunc:"8" }}{% endautoescape %}', {"a": '"Unsafe" http://example.com/x=&y=', "b": mark_safe('"Safe" http://example.com?x=&y=')}, u'"Unsafe" <a href="http://example.com/x=&y=" rel="nofollow">http:...</a> "Safe" <a href="http://example.com?x=&y=" rel="nofollow">http:...</a>'),
|
||||
'filter-urlizetrunc02': ('{{ a|urlizetrunc:"8" }} {{ b|urlizetrunc:"8" }}', {"a": '"Unsafe" http://example.com/x=&y=', "b": mark_safe('"Safe" http://example.com?x=&y=')}, u'"Unsafe" <a href="http://example.com/x=&y=" rel="nofollow">http:...</a> "Safe" <a href="http://example.com?x=&y=" rel="nofollow">http:...</a>'),
|
||||
|
||||
'filter-wordcount01': ('{% autoescape off %}{{ a|wordcount }} {{ b|wordcount }}{% endautoescape %}', {"a": "a & b", "b": mark_safe("a & b")}, "3 3"),
|
||||
'filter-wordcount02': ('{{ a|wordcount }} {{ b|wordcount }}', {"a": "a & b", "b": mark_safe("a & b")}, "3 3"),
|
||||
@ -240,7 +244,7 @@ def get_filter_tests():
|
||||
'chaining13': ('{{ a|safe|force_escape }}', {"a": "a < b"}, "a < b"),
|
||||
'chaining14': ('{% autoescape off %}{{ a|safe|force_escape }}{% endautoescape %}', {"a": "a < b"}, "a < b"),
|
||||
|
||||
# Filters decorated with stringfilter still respect is_safe.
|
||||
# Filters decorated with stringfilter still respect is_safe.
|
||||
'autoescape-stringfilter01': (r'{{ unsafe|capfirst }}', {'unsafe': UnsafeClass()}, 'You & me'),
|
||||
'autoescape-stringfilter02': (r'{% autoescape off %}{{ unsafe|capfirst }}{% endautoescape %}', {'unsafe': UnsafeClass()}, 'You & me'),
|
||||
'autoescape-stringfilter03': (r'{{ safe|capfirst }}', {'safe': SafeClass()}, 'You > me'),
|
||||
|
@ -736,7 +736,7 @@ class Templates(unittest.TestCase):
|
||||
'i18n09': ('{% load i18n %}{% trans "Page not found" noop %}', {'LANGUAGE_CODE': 'de'}, "Page not found"),
|
||||
|
||||
# translation of a variable with a translated filter
|
||||
'i18n10': ('{{ bool|yesno:_("ja,nein") }}', {'bool': True}, 'ja'),
|
||||
'i18n10': ('{{ bool|yesno:_("yes,no,maybe") }}', {'bool': True, 'LANGUAGE_CODE': 'de'}, 'Ja'),
|
||||
|
||||
# translation of a variable with a non-translated filter
|
||||
'i18n11': ('{{ bool|yesno:"ja,nein" }}', {'bool': True}, 'ja'),
|
||||
|
Loading…
x
Reference in New Issue
Block a user