summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoulder Sprinters <boulder-sprinters@djangoproject.com>2007-06-18 16:43:17 +0000
committerBoulder Sprinters <boulder-sprinters@djangoproject.com>2007-06-18 16:43:17 +0000
commit750549569ea8d911db0397bd034406d5ce35d923 (patch)
treee516db51e7fb41b457c2caa64f54d7210128840f
parent1f09aa1e7b4079e22d1dfcde0f7d4e571389d8b5 (diff)
downloaddjango-750549569ea8d911db0397bd034406d5ce35d923.tar.gz
boulder-oracle-sprint: Merged to [5490]
git-svn-id: http://code.djangoproject.com/svn/django/branches/boulder-oracle-sprint@5491 bcc190cf-cafb-0310-a4f2-bffc1f526a37
-rw-r--r--AUTHORS1
-rw-r--r--django/conf/locale/sv/LC_MESSAGES/django.mobin39640 -> 45632 bytes
-rw-r--r--django/conf/locale/sv/LC_MESSAGES/django.po1888
-rw-r--r--django/conf/locale/sv/LC_MESSAGES/djangojs.po3
-rw-r--r--django/contrib/admin/templatetags/admin_modify.py13
-rw-r--r--django/contrib/admin/templatetags/adminapplist.py4
-rw-r--r--django/contrib/admin/templatetags/log.py4
-rw-r--r--django/contrib/auth/__init__.py5
-rw-r--r--django/contrib/comments/templatetags/comments.py18
-rw-r--r--django/contrib/sessions/models.py6
-rw-r--r--django/core/servers/basehttp.py9
-rw-r--r--django/http/__init__.py18
-rw-r--r--django/middleware/common.py8
-rw-r--r--django/newforms/models.py5
-rw-r--r--django/oldforms/__init__.py4
-rw-r--r--django/shortcuts/__init__.py2
-rw-r--r--django/template/__init__.py88
-rw-r--r--django/template/defaulttags.py126
-rw-r--r--django/template/loader.py33
-rw-r--r--django/template/loader_tags.py25
-rw-r--r--django/test/utils.py20
-rw-r--r--django/utils/itercompat.py24
-rw-r--r--django/views/debug.py6
-rw-r--r--django/views/defaults.py4
-rw-r--r--django/views/generic/create_update.py6
-rw-r--r--django/views/generic/date_based.py12
-rw-r--r--django/views/generic/list_detail.py4
-rw-r--r--django/views/generic/simple.py2
-rw-r--r--django/views/static.py2
-rw-r--r--docs/authentication.txt4
-rw-r--r--docs/newforms.txt6
-rw-r--r--docs/templates_python.txt63
32 files changed, 1619 insertions, 794 deletions
diff --git a/AUTHORS b/AUTHORS
index cd1bb2002f..cd136fe06c 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -221,6 +221,7 @@ answer newbie questions, and generally made Django that much better:
Aaron Swartz <http://www.aaronsw.com/>
Ville Säävuori <http://www.unessa.net/>
Tyson Tate <tyson@fallingbullets.com>
+ Frank Tegtmeyer <fte@fte.to>
thebjorn <bp@datakortet.no>
Zach Thompson <zthompson47@gmail.com>
Tom Tobin
diff --git a/django/conf/locale/sv/LC_MESSAGES/django.mo b/django/conf/locale/sv/LC_MESSAGES/django.mo
index cd91c18cb7..5654541a4e 100644
--- a/django/conf/locale/sv/LC_MESSAGES/django.mo
+++ b/django/conf/locale/sv/LC_MESSAGES/django.mo
Binary files differ
diff --git a/django/conf/locale/sv/LC_MESSAGES/django.po b/django/conf/locale/sv/LC_MESSAGES/django.po
index befde10e77..db542460e6 100644
--- a/django/conf/locale/sv/LC_MESSAGES/django.po
+++ b/django/conf/locale/sv/LC_MESSAGES/django.po
@@ -2,17 +2,13 @@
# Copyright (C) 2005
# This file is distributed under the same license as the Django package.
#
-#
-# Robin Sonefors <ozamosi@blinkenlights.se>, 2005.
-# Ludvig Ericson <ludvig.ericson@gmail.com>, 2007.
-# Mikko Hellsing <mikko@sorl.net>, 2007.
msgid ""
msgstr ""
"Project-Id-Version: django\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2007-03-06 00:17+0100\n"
+"POT-Creation-Date: 2007-06-15 17:35+0200\n"
"PO-Revision-Date: 2007-03-06 10:30+0100\n"
-"Last-Translator: Mikko Hellsing <mikko@sorl.net>\n"
+"Last-Translator: Ludvig Ericson <ludvig.ericson@gmail.com>\n"
"Language-Team: Django I18N <Django-I18N@googlegroups.com>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -21,62 +17,62 @@ msgstr ""
"X-Poedit-Language: Swedish\n"
"X-Poedit-Country: SWEDEN\n"
-#: oldforms/__init__.py:352 db/models/fields/__init__.py:116
-#: db/models/fields/__init__.py:273 db/models/fields/__init__.py:609
-#: db/models/fields/__init__.py:620 newforms/models.py:177
-#: newforms/fields.py:78 newforms/fields.py:374 newforms/fields.py:450
-#: newforms/fields.py:461
+#: oldforms/__init__.py:357 db/models/fields/__init__.py:121
+#: db/models/fields/__init__.py:278 db/models/fields/__init__.py:675
+#: db/models/fields/__init__.py:686 newforms/models.py:185
+#: newforms/fields.py:87 newforms/fields.py:444 newforms/fields.py:520
+#: newforms/fields.py:531
msgid "This field is required."
-msgstr "Detta fältet är obligatoriskt."
+msgstr "Det här fältet är obligatoriskt."
-#: oldforms/__init__.py:387
+#: oldforms/__init__.py:392
#, python-format
msgid "Ensure your text is less than %s character."
msgid_plural "Ensure your text is less than %s characters."
msgstr[0] "Se till att din text är kortare än %s tecken."
msgstr[1] "Se till att din text är kortare än %s tecken."
-#: oldforms/__init__.py:392
+#: oldforms/__init__.py:397
msgid "Line breaks are not allowed here."
msgstr "Radbrytningar är inte tillåtna här."
-#: oldforms/__init__.py:493 oldforms/__init__.py:566 oldforms/__init__.py:605
+#: oldforms/__init__.py:498 oldforms/__init__.py:571 oldforms/__init__.py:610
#, python-format
msgid "Select a valid choice; '%(data)s' is not in %(choices)s."
msgstr "Välj ett giltigt alternativ. '%(data)s' finns inte bland %(choices)s."
-#: oldforms/__init__.py:572 newforms/widgets.py:170
+#: oldforms/__init__.py:577 newforms/widgets.py:182
#: contrib/admin/filterspecs.py:150
msgid "Unknown"
msgstr "Okänt"
-#: oldforms/__init__.py:572 newforms/widgets.py:170
+#: oldforms/__init__.py:577 newforms/widgets.py:182
#: contrib/admin/filterspecs.py:143
msgid "Yes"
msgstr "Ja"
-#: oldforms/__init__.py:572 newforms/widgets.py:170
+#: oldforms/__init__.py:577 newforms/widgets.py:182
#: contrib/admin/filterspecs.py:143
msgid "No"
msgstr "Nej"
-#: oldforms/__init__.py:667 core/validators.py:173 core/validators.py:444
+#: oldforms/__init__.py:672 core/validators.py:175 core/validators.py:453
msgid "No file was submitted. Check the encoding type on the form."
-msgstr "Ingen fil skickad. Kontrollera enkodningen i form taggen."
+msgstr "Ingen fil skickades. Kontrollera kodningnstypen i formen."
-#: oldforms/__init__.py:669
+#: oldforms/__init__.py:674
msgid "The submitted file is empty."
msgstr "Den insända filen är tom."
-#: oldforms/__init__.py:725
+#: oldforms/__init__.py:730
msgid "Enter a whole number between -32,768 and 32,767."
msgstr "Fyll i ett heltal mellan -32768 och 32767."
-#: oldforms/__init__.py:735
+#: oldforms/__init__.py:740
msgid "Enter a positive number."
msgstr "Fyll i ett positivt heltal."
-#: oldforms/__init__.py:745
+#: oldforms/__init__.py:750
msgid "Enter a whole number between 0 and 32,767."
msgstr "Fyll i ett heltal mellan 0 och 32767."
@@ -90,35 +86,45 @@ msgstr "%(object)s med typen %(type)s finns redan för %(field)s."
msgid "and"
msgstr "och"
-#: db/models/fields/__init__.py:42
+#: db/models/fields/__init__.py:46
#, python-format
msgid "%(optname)s with this %(fieldname)s already exists."
msgstr "%(optname)s med det här %(fieldname)s finns redan."
-#: db/models/fields/__init__.py:366
+#: db/models/fields/__init__.py:373
msgid "This value must be an integer."
msgstr "Det här värdet måste vara ett heltal."
-#: db/models/fields/__init__.py:401
+#: db/models/fields/__init__.py:408
msgid "This value must be either True or False."
msgstr "Det här värdet måste vara True eller False"
-#: db/models/fields/__init__.py:422
+#: db/models/fields/__init__.py:429
msgid "This field cannot be null."
-msgstr "Det här fältet får inte vara null."
+msgstr "Det här fältet kan inte vara null."
-#: db/models/fields/__init__.py:456 core/validators.py:147
+#: db/models/fields/__init__.py:463 core/validators.py:149
msgid "Enter a valid date in YYYY-MM-DD format."
-msgstr "Fyll i ett giltigt datum i formatet ÅÅÅÅ-MM-DD."
+msgstr "Fyll i ett giltigt datum i ÅÅÅÅ-MM-DD format."
-#: db/models/fields/__init__.py:525 core/validators.py:156
+#: db/models/fields/__init__.py:532 core/validators.py:158
msgid "Enter a valid date/time in YYYY-MM-DD HH:MM format."
-msgstr "Fyll i en giltig tidpunkt i formatet ÅÅÅÅ-MM-DD HH:MM"
+msgstr "Fyll i en giltig tidpunkt i ÅÅÅÅ-MM-DD HH:MM format"
+
+#: db/models/fields/__init__.py:592
+#, fuzzy
+msgid "This value must be a decimal number."
+msgstr "Det här värdet måste vara ett heltal."
-#: db/models/fields/__init__.py:629
+#: db/models/fields/__init__.py:695
msgid "Enter a valid filename."
msgstr "Fyll i ett giltigt filnamn."
+#: db/models/fields/__init__.py:818
+#, fuzzy
+msgid "This value must be either None, True or False."
+msgstr "Det här värdet måste vara antingen True eller False."
+
#: db/models/fields/related.py:53
#, python-format
msgid "Please enter a valid %s."
@@ -129,15 +135,20 @@ msgid "Separate multiple IDs with commas."
msgstr "Separera flera ID:n med kommatecken."
#: db/models/fields/related.py:644
-msgid "Hold down \"Control\", or \"Command\" on a Mac, to select more than one."
-msgstr "Håll ner \"Control\", eller \"Command\" på en Mac, för att välja mer än en."
+msgid ""
+"Hold down \"Control\", or \"Command\" on a Mac, to select more than one."
+msgstr ""
+"Håll ner \"Control\", eller \"Command\" på en Mac, för att välja mer än en."
#: db/models/fields/related.py:691
#, python-format
msgid "Please enter valid %(self)s IDs. The value %(value)r is invalid."
-msgid_plural "Please enter valid %(self)s IDs. The values %(value)r are invalid."
-msgstr[0] "Var god och fyll giltiga %(self)s ID-nummer. Värdet %(value)r är ogiltigt."
-msgstr[1] "Var god och fyll giltiga %(self)s ID-nummer. Värdena %(value)r är ogiltiga."
+msgid_plural ""
+"Please enter valid %(self)s IDs. The values %(value)r are invalid."
+msgstr[0] ""
+"Var god och fyll giltiga %(self)s ID-nummer. Värdet %(value)r är ogiltigt."
+msgstr[1] ""
+"Var god och fyll giltiga %(self)s ID-nummer. Värdena %(value)r är ogiltiga."
#: conf/global_settings.py:39
msgid "Arabic"
@@ -148,150 +159,167 @@ msgid "Bengali"
msgstr "Bengaliska"
#: conf/global_settings.py:41
+#, fuzzy
+msgid "Bulgarian"
+msgstr "Ungerska"
+
+#: conf/global_settings.py:42
msgid "Catalan"
msgstr "Katalanska"
-#: conf/global_settings.py:42
+#: conf/global_settings.py:43
msgid "Czech"
msgstr "Tjeckiska"
-#: conf/global_settings.py:43
+#: conf/global_settings.py:44
msgid "Welsh"
msgstr "Walesiska"
-#: conf/global_settings.py:44
+#: conf/global_settings.py:45
msgid "Danish"
msgstr "Danska"
-#: conf/global_settings.py:45
+#: conf/global_settings.py:46
msgid "German"
msgstr "Tyska"
-#: conf/global_settings.py:46
+#: conf/global_settings.py:47
msgid "Greek"
msgstr "Grekiska"
-#: conf/global_settings.py:47
+#: conf/global_settings.py:48
msgid "English"
msgstr "Engelska"
-#: conf/global_settings.py:48
+#: conf/global_settings.py:49
msgid "Spanish"
msgstr "Spanska"
-#: conf/global_settings.py:49
+#: conf/global_settings.py:50
msgid "Argentinean Spanish"
msgstr "Argentisk Spanska"
-#: conf/global_settings.py:50
+#: conf/global_settings.py:51
msgid "Finnish"
msgstr "Finska"
-#: conf/global_settings.py:51
+#: conf/global_settings.py:52
msgid "French"
msgstr "Franska"
-#: conf/global_settings.py:52
+#: conf/global_settings.py:53
msgid "Galician"
msgstr "Galisiska"
-#: conf/global_settings.py:53
+#: conf/global_settings.py:54
msgid "Hungarian"
msgstr "Ungerska"
-#: conf/global_settings.py:54
+#: conf/global_settings.py:55
msgid "Hebrew"
msgstr "Hebreiska"
-#: conf/global_settings.py:55
+#: conf/global_settings.py:56
msgid "Icelandic"
msgstr "Isländska"
-#: conf/global_settings.py:56
+#: conf/global_settings.py:57
msgid "Italian"
msgstr "Italienska"
-#: conf/global_settings.py:57
+#: conf/global_settings.py:58
msgid "Japanese"
msgstr "Japanska"
-#: conf/global_settings.py:58
+#: conf/global_settings.py:59
+msgid "Korean"
+msgstr "Koreanska"
+
+#: conf/global_settings.py:60
msgid "Kannada"
msgstr "Kannada"
-#: conf/global_settings.py:59
+#: conf/global_settings.py:61
msgid "Latvian"
msgstr "Lettiska"
-#: conf/global_settings.py:60
+#: conf/global_settings.py:62
msgid "Macedonian"
msgstr "Makedonska"
-#: conf/global_settings.py:61
+#: conf/global_settings.py:63
msgid "Dutch"
msgstr "Holländska"
-#: conf/global_settings.py:62
+#: conf/global_settings.py:64
msgid "Norwegian"
msgstr "Norska"
-#: conf/global_settings.py:63
+#: conf/global_settings.py:65
msgid "Polish"
msgstr "Polska"
-#: conf/global_settings.py:64
+#: conf/global_settings.py:66
+msgid "Portugese"
+msgstr "Portugisiska"
+
+#: conf/global_settings.py:67
msgid "Brazilian"
msgstr "Brasilianska"
-#: conf/global_settings.py:65
+#: conf/global_settings.py:68
msgid "Romanian"
msgstr "Rumänska"
-#: conf/global_settings.py:66
+#: conf/global_settings.py:69
msgid "Russian"
msgstr "Ryska"
-#: conf/global_settings.py:67
+#: conf/global_settings.py:70
msgid "Slovak"
msgstr "Slovakiska"
-#: conf/global_settings.py:68
+#: conf/global_settings.py:71
msgid "Slovenian"
msgstr "Slovenska"
-#: conf/global_settings.py:69
+#: conf/global_settings.py:72
msgid "Serbian"
msgstr "Serbiska"
-#: conf/global_settings.py:70
+#: conf/global_settings.py:73
msgid "Swedish"
msgstr "Svenska"
-#: conf/global_settings.py:71
+#: conf/global_settings.py:74
msgid "Tamil"
msgstr "Tamil"
-#: conf/global_settings.py:72
+#: conf/global_settings.py:75
+msgid "Telugu"
+msgstr "Telugu"
+
+#: conf/global_settings.py:76
msgid "Turkish"
msgstr "Turkiska"
-#: conf/global_settings.py:73
+#: conf/global_settings.py:77
msgid "Ukrainian"
msgstr "Ukrainska"
-#: conf/global_settings.py:74
+#: conf/global_settings.py:78
msgid "Simplified Chinese"
msgstr "Förenklad Kinesiska"
-#: conf/global_settings.py:75
+#: conf/global_settings.py:79
msgid "Traditional Chinese"
msgstr "Traditionell Kinesiska"
-#: core/validators.py:64
+#: core/validators.py:65
msgid "This value must contain only letters, numbers and underscores."
msgstr "Det här värdet får bara innehålla bokstäver, tal och understräck."
-#: core/validators.py:68
+#: core/validators.py:69
msgid ""
"This value must contain only letters, numbers, underscores, dashes or "
"slashes."
@@ -299,97 +327,99 @@ msgstr ""
"Det här värdet får bara innehålla bokstäver, siffror, understräck, sträck "
"och snedsträck"
-#: core/validators.py:72
+#: core/validators.py:73
msgid "This value must contain only letters, numbers, underscores or hyphens."
-msgstr "Det här värdet får bara innehålla bokstäver, siffror, understräck eller sträck ."
+msgstr ""
+"Det här värdet får bara innehålla bokstäver, siffror, understräck eller "
+"bindessträck."
-#: core/validators.py:76
+#: core/validators.py:77
msgid "Uppercase letters are not allowed here."
msgstr "Stora bokstäver är inte tillåtna här."
-#: core/validators.py:80
+#: core/validators.py:81
msgid "Lowercase letters are not allowed here."
msgstr "Små bokstäver är inte tillåtna här."
-#: core/validators.py:87
+#: core/validators.py:88
msgid "Enter only digits separated by commas."
msgstr "Fyll enbart i siffror avskilda med kommatecken."
-#: core/validators.py:99
+#: core/validators.py:100
msgid "Enter valid e-mail addresses separated by commas."
msgstr "Fyll i giltiga e-mailadresser avskilda med kommatecken."
-#: core/validators.py:103
+#: core/validators.py:104
msgid "Please enter a valid IP address."
msgstr "Var god fyll i en giltigt IP-adress."
-#: core/validators.py:107
+#: core/validators.py:108
msgid "Empty values are not allowed here."
msgstr "Tomma värden är inte tillåtna här."
-#: core/validators.py:111
+#: core/validators.py:112
msgid "Non-numeric characters aren't allowed here."
msgstr "Icke-numeriska tecken är inte tillåtna här."
-#: core/validators.py:115
+#: core/validators.py:116
msgid "This value can't be comprised solely of digits."
msgstr "Det här värdet kan inte enbart bestå av siffror."
-#: core/validators.py:120 newforms/fields.py:126
+#: core/validators.py:121 newforms/fields.py:135
msgid "Enter a whole number."
msgstr "Fyll i ett heltal."
-#: core/validators.py:124
+#: core/validators.py:125
msgid "Only alphabetical characters are allowed here."
msgstr "Endast bokstäver är tillåtna här."
-#: core/validators.py:139
+#: core/validators.py:140
msgid "Year must be 1900 or later."
msgstr "Årtal måste vara 1900 eller senare."
-#: core/validators.py:143
-#, python-format
-msgid "Invalid date: %s."
+#: core/validators.py:144
+#, fuzzy, python-format
+msgid "Invalid date: %s"
msgstr "Felaktigt datum: %s"
-#: core/validators.py:152
+#: core/validators.py:154
msgid "Enter a valid time in HH:MM format."
-msgstr "Fyll i en giltig tid i formatet HH:MM"
+msgstr "Fyll i en giltig tid i HH:MM format."
-#: core/validators.py:161 newforms/fields.py:269
+#: core/validators.py:163 newforms/fields.py:339
msgid "Enter a valid e-mail address."
msgstr "Fyll i en giltig e-mailadress."
-#: core/validators.py:177
+#: core/validators.py:179
msgid ""
"Upload a valid image. The file you uploaded was either not an image or a "
"corrupted image."
msgstr ""
-"Ladda upp en giltig bild. Filen du laddade upp var antingen ingen bild eller en "
-"korrupt bild."
+"Ladda upp en giltig bild. Filen du laddade upp var antingen ingen bild eller "
+"en korrupt bild."
-#: core/validators.py:184
+#: core/validators.py:186
#, python-format
msgid "The URL %s does not point to a valid image."
-msgstr "URL:en %s pekar inte på en giltig bild."
+msgstr "URL:en %s pekar inte mot en giltig bild."
-#: core/validators.py:188
+#: core/validators.py:190
#, python-format
msgid "Phone numbers must be in XXX-XXX-XXXX format. \"%s\" is invalid."
msgstr ""
-"Telefonnummer måste vara i det amerikanska formatet XXX-XXX-XXXX. \"%s\" är "
+"Telefonnummer måste vara i det amerikanska XXX-XXX-XXXX formated. \"%s\" är "
"ogiltigt."
-#: core/validators.py:196
+#: core/validators.py:198
#, python-format
msgid "The URL %s does not point to a valid QuickTime video."
msgstr "URL:en %s pekar inte på en giltig QuickTime-video."
-#: core/validators.py:200
+#: core/validators.py:202
msgid "A valid URL is required."
msgstr "En giltig URL krävs."
-#: core/validators.py:214
+#: core/validators.py:216
#, python-format
msgid ""
"Valid HTML is required. Specific errors are:\n"
@@ -398,133 +428,146 @@ msgstr ""
"Giltig HTML krävs. Specifika fel är:\n"
"%s"
-#: core/validators.py:221
+#: core/validators.py:223
#, python-format
msgid "Badly formed XML: %s"
msgstr "Missformad XML: %s"
-#: core/validators.py:238
+#: core/validators.py:240
#, python-format
msgid "Invalid URL: %s"
msgstr "Felaktig URL: %s"
-#: core/validators.py:243 core/validators.py:245
+#: core/validators.py:245 core/validators.py:247
#, python-format
msgid "The URL %s is a broken link."
msgstr "URL:en %s är en trasig länk."
-#: core/validators.py:251
+#: core/validators.py:253
msgid "Enter a valid U.S. state abbreviation."
-msgstr "Fyll i en giltig förkortning för en amerikansk delstat"
+msgstr "Fyll i en giltig förkortning för en amerikansk delstat."
-#: core/validators.py:265
+#: core/validators.py:267
#, python-format
msgid "Watch your mouth! The word %s is not allowed here."
msgid_plural "Watch your mouth! The words %s are not allowed here."
msgstr[0] "Akta din tunga! Ordet %s är inte tillåtet här."
msgstr[1] "Akta din tunga! Orden %s är inte tillåtna här."
-#: core/validators.py:272
+#: core/validators.py:274
#, python-format
msgid "This field must match the '%s' field."
msgstr "Det här fältet måste matcha fältet '%s'."
-#: core/validators.py:291
+#: core/validators.py:293
msgid "Please enter something for at least one field."
-msgstr "Fyll i något i minst ett fält."
+msgstr "Var god fyll i minst ett fält."
-#: core/validators.py:300 core/validators.py:311
+#: core/validators.py:302 core/validators.py:313
msgid "Please enter both fields or leave them both empty."
-msgstr "Fyll antingen i båda fälten, eller lämna båda tomma"
+msgstr "Fyll antingen i båda fälten, eller lämna båda tomma."
-#: core/validators.py:319
+#: core/validators.py:321
#, python-format
msgid "This field must be given if %(field)s is %(value)s"
msgstr "Det är fältet måste anges om %(field)s är %(value)s"
-#: core/validators.py:332
+#: core/validators.py:334
#, python-format
msgid "This field must be given if %(field)s is not %(value)s"
msgstr "Det här fältet måste anges om %(field)s inte är %(value)s"
-#: core/validators.py:351
+#: core/validators.py:353
msgid "Duplicate values are not allowed."
msgstr "Upprepade värden är inte tillåtna."
-#: core/validators.py:366
+#: core/validators.py:368
#, python-format
msgid "This value must be between %(lower)s and %(upper)s."
-msgstr "Det här värdet måste mellan %(lower)s och %(upper)s."
+msgstr "Det här värdet måste vara mellan %(lower)s och %(upper)s."
-#: core/validators.py:368
+#: core/validators.py:370
#, python-format
msgid "This value must be at least %s."
-msgstr "Det här värdet måste minsta vara %s."
+msgstr "Det här värdet måste vara minst %s."
-#: core/validators.py:370
+#: core/validators.py:372
#, python-format
msgid "This value must be no more than %s."
msgstr "Det här värdet får inte vara mer än %s."
-#: core/validators.py:406
+#: core/validators.py:408
#, python-format
msgid "This value must be a power of %s."
-msgstr "Det här värdet måste vara en multipel av %s."
+msgstr "Det här värdet måste vara en potens av %s."
#: core/validators.py:417
msgid "Please enter a valid decimal number."
msgstr "Fyll i ett giltigt decimaltal."
-#: core/validators.py:421
+#: core/validators.py:423
#, python-format
msgid "Please enter a valid decimal number with at most %s total digit."
-msgid_plural "Please enter a valid decimal number with at most %s total digits."
-msgstr[0] "Fyll i ett giltigt decimaltal med mindre än %s siffra totalt."
-msgstr[1] "Fyll i ett giltigt decimaltal med mindre än %s siffror totalt."
+msgid_plural ""
+"Please enter a valid decimal number with at most %s total digits."
+msgstr[0] "Fyll i ett giltigt decimaltal med högst %s siffra totalt."
+msgstr[1] "Fyll i ett giltigt decimaltal med högst %s siffror totalt."
-#: core/validators.py:424
+#: core/validators.py:426
#, python-format
-msgid "Please enter a valid decimal number with a whole part of at most %s digit."
-msgid_plural "Please enter a valid decimal number with a whole part of at most %s digits."
-msgstr[0] "Fyll i ett giltigt decimaltal med en heltalsdel som inte är mer än %s siffra."
-msgstr[1] "Fyll i ett giltigt decimaltal med en heltalsdel som inte är mer än %s siffror."
+msgid ""
+"Please enter a valid decimal number with a whole part of at most %s digit."
+msgid_plural ""
+"Please enter a valid decimal number with a whole part of at most %s digits."
+msgstr[0] ""
+"Fyll i ett giltigt decimaltal med en heltalsdel som högst är %s siffra."
+msgstr[1] ""
+"Fyll i ett giltigt decimaltal med en heltalsdel som högst är %s siffror."
-#: core/validators.py:427
+#: core/validators.py:429
#, python-format
msgid "Please enter a valid decimal number with at most %s decimal place."
-msgid_plural "Please enter a valid decimal number with at most %s decimal places."
-msgstr[0] "Fyll i ett giltigt decimaltal med %s decimal som mest."
-msgstr[1] "Fyll i ett giltigt decimaltal med %s decimaler som mest."
+msgid_plural ""
+"Please enter a valid decimal number with at most %s decimal places."
+msgstr[0] "Fyll i ett giltigt decimaltal med högst %s decimal."
+msgstr[1] "Fyll i ett giltigt decimaltal med högst %s decimaler."
#: core/validators.py:437
+msgid "Please enter a valid floating point number."
+msgstr "Fyll i ett giltigt flyttal."
+
+#: core/validators.py:446
#, python-format
msgid "Make sure your uploaded file is at least %s bytes big."
msgstr "Se till att filen du laddade upp är minst %s bytes stor."
-#: core/validators.py:438
+#: core/validators.py:447
#, python-format
msgid "Make sure your uploaded file is at most %s bytes big."
msgstr "Se till att filen du laddade upp är som mest %s bytes stor."
-#: core/validators.py:455
+#: core/validators.py:464
msgid "The format for this field is wrong."
msgstr "Formatet på det här fältet är fel."
-#: core/validators.py:470
+#: core/validators.py:479
msgid "This field is invalid."
msgstr "Det här fältet är ogiltigt."
-#: core/validators.py:506
+#: core/validators.py:515
#, python-format
msgid "Could not retrieve anything from %s."
msgstr "Kunde inte hämta något från %s."
-#: core/validators.py:509
+#: core/validators.py:518
#, python-format
-msgid "The URL %(url)s returned the invalid Content-Type header '%(contenttype)s'."
-msgstr "URL:en %(url)s returnerade den ogiltiga Content-Type headern '%(contenttype)s'"
+msgid ""
+"The URL %(url)s returned the invalid Content-Type header '%(contenttype)s'."
+msgstr ""
+"URL:en %(url)s returnerade den ogiltiga Content-Type headern '%(contenttype)"
+"s'"
-#: core/validators.py:542
+#: core/validators.py:551
#, python-format
msgid ""
"Please close the unclosed %(tag)s tag from line %(line)s. (Line starts with "
@@ -533,7 +576,7 @@ msgstr ""
"Var god avsluta den oavslutade taggen %(tag)s på rad %(line)s. (Raden börjar "
"med \"%(start)s\".)"
-#: core/validators.py:546
+#: core/validators.py:555
#, python-format
msgid ""
"Some text starting on line %(line)s is not allowed in that context. (Line "
@@ -542,7 +585,7 @@ msgstr ""
"En del text från rad %(line)s är inte tillåtet i det sammanhanget. (Raden "
"börjar med \"%(start)s\".)"
-#: core/validators.py:551
+#: core/validators.py:560
#, python-format
msgid ""
"\"%(attr)s\" on line %(line)s is an invalid attribute. (Line starts with \"%"
@@ -551,7 +594,7 @@ msgstr ""
"\"%(attr)s\" på rad %(line)s är inte ett giltigt attribut. (Raden startar "
"med \"%(start)s\".)"
-#: core/validators.py:556
+#: core/validators.py:565
#, python-format
msgid ""
"\"<%(tag)s>\" on line %(line)s is an invalid tag. (Line starts with \"%"
@@ -560,7 +603,7 @@ msgstr ""
"\"<%(tag)s>\" på rad %(line)s är en ogiltig tagg. (Raden börjar med \"%"
"(start)s\".)"
-#: core/validators.py:560
+#: core/validators.py:569
#, python-format
msgid ""
"A tag on line %(line)s is missing one or more required attributes. (Line "
@@ -569,7 +612,7 @@ msgstr ""
"En tagg på rad %(line)s saknar en eller flera nödvändiga attribut. (Raden "
"börjar med \"%(start)s\".)"
-#: core/validators.py:565
+#: core/validators.py:574
#, python-format
msgid ""
"The \"%(attr)s\" attribute on line %(line)s has an invalid value. (Line "
@@ -580,11 +623,13 @@ msgstr ""
#: views/generic/create_update.py:43
#, python-format
+#, fuzzy
msgid "The %(verbose_name)s was created successfully."
msgstr "%(verbose_name)s skapades framgångsrikt."
#: views/generic/create_update.py:117
#, python-format
+#, fuzzy
msgid "The %(verbose_name)s was updated successfully."
msgstr " %(verbose_name)s uppdaterades framgångsrikt."
@@ -593,258 +638,160 @@ msgstr " %(verbose_name)s uppdaterades framgångsrikt."
msgid "The %(verbose_name)s was deleted."
msgstr "%(verbose_name)s togs bort."
-#: newforms/models.py:164 newforms/fields.py:360
+#: newforms/models.py:172 newforms/fields.py:432
msgid "Select a valid choice. That choice is not one of the available choices."
-msgstr "Välj ett giltigt alternativ. Det valet finns inte bland tillgängliga alternativ."
+msgstr ""
+"Välj ett giltigt alternativ. Det valet finns inte bland tillgängliga "
+"alternativ."
-#: newforms/models.py:181 newforms/fields.py:378 newforms/fields.py:454
+#: newforms/models.py:189 newforms/fields.py:448 newforms/fields.py:524
msgid "Enter a list of values."
msgstr "Fyll i en lista med värden."
-#: newforms/models.py:187 newforms/fields.py:387
+#: newforms/models.py:195 newforms/fields.py:457
#, python-format
msgid "Select a valid choice. %s is not one of the available choices."
-msgstr "Välj ett giltigt alternativ. '%s' finns inte bland tillgängliga alternativ."
+msgstr ""
+"Välj ett giltigt alternativ. '%s' finns inte bland tillgängliga alternativ."
-#: newforms/fields.py:101 newforms/fields.py:254
+#: newforms/fields.py:110 newforms/fields.py:324
#, python-format
msgid "Ensure this value has at most %d characters."
-msgstr "Se till att din text inte har mer än %d tecken."
+msgstr "Säkerställ att detta värdet har högst %d tecken."
-#: newforms/fields.py:103 newforms/fields.py:256
+#: newforms/fields.py:112 newforms/fields.py:326
#, python-format
msgid "Ensure this value has at least %d characters."
-msgstr "Se till att din text har minst %d tecken."
+msgstr "Säkerställ att detta värdet har minst %d tecken."
-#: newforms/fields.py:128
+#: newforms/fields.py:137 newforms/fields.py:160 newforms/fields.py:192
#, python-format
msgid "Ensure this value is less than or equal to %s."
-msgstr "Se till att detta värdet är mindre än eller lika med %s."
+msgstr "Säkerställ att detta värdet är mindre eller lika med %s."
-#: newforms/fields.py:130
+#: newforms/fields.py:139 newforms/fields.py:162 newforms/fields.py:194
#, python-format
msgid "Ensure this value is greater than or equal to %s."
-msgstr "Se till att detta värde är större eller lika med %s."
+msgstr "Säkerställ att detta värdet är mer eller lika med %s."
+
+#: newforms/fields.py:158 newforms/fields.py:186
+msgid "Enter a number."
+msgstr "Fyll i ett tal."
+
+#: newforms/fields.py:196
+#, python-format
+msgid "Ensure that there are no more than %s digits in total."
+msgstr "Säkerställ att det inte finns mer än %s siffror totalt."
-#: newforms/fields.py:163
+#: newforms/fields.py:198
+#, python-format
+msgid "Ensure that there are no more than %s decimal places."
+msgstr "Säkerställ att det inte finns mer än %s decimaler."
+
+#: newforms/fields.py:200
+#, python-format
+msgid "Ensure that there are no more than %s digits before the decimal point."
+msgstr "Säkerställ att det inte finns mer än %s siffror före kommatecknet."
+
+#: newforms/fields.py:233
msgid "Enter a valid date."
msgstr "Fyll i ett giltigt datum."
-#: newforms/fields.py:190
+#: newforms/fields.py:260
msgid "Enter a valid time."
msgstr "Fyll i en giltig tid."
-#: newforms/fields.py:226
+#: newforms/fields.py:296
msgid "Enter a valid date/time."
msgstr "Fyll i ett giltigt datum/tid."
-#: newforms/fields.py:240
+#: newforms/fields.py:310
msgid "Enter a valid value."
msgstr "Fyll i ett giltigt värde."
-#: newforms/fields.py:287 newforms/fields.py:309
+#: newforms/fields.py:357 newforms/fields.py:379
msgid "Enter a valid URL."
msgstr "Fyll i ett giltigt URL."
-#: newforms/fields.py:311
+#: newforms/fields.py:381
msgid "This URL appears to be a broken link."
-msgstr "Detta URL verkar vara en trasig länk."
-
-#: contrib/contenttypes/models.py:26
-msgid "python model class name"
-msgstr "python modell klass namn"
-
-#: contrib/contenttypes/models.py:29
-msgid "content type"
-msgstr "innehållstyp"
-
-#: contrib/contenttypes/models.py:30
-msgid "content types"
-msgstr "innehållstyper"
-
-#: contrib/auth/views.py:39
-msgid "Logged out"
-msgstr "Utloggad"
-
-#: contrib/auth/models.py:38 contrib/auth/models.py:57
-msgid "name"
-msgstr "namn"
-
-#: contrib/auth/models.py:40
-msgid "codename"
-msgstr "kodnamn"
-
-#: contrib/auth/models.py:42
-msgid "permission"
-msgstr "rättighet"
-
-#: contrib/auth/models.py:43 contrib/auth/models.py:58
-msgid "permissions"
-msgstr "rättigheter"
-
-#: contrib/auth/models.py:60
-msgid "group"
-msgstr "grupp"
+msgstr "Denna URL verkar vara en trasig länk."
-#: contrib/auth/models.py:61 contrib/auth/models.py:100
-msgid "groups"
-msgstr "grupper"
-
-#: contrib/auth/models.py:90
-msgid "username"
-msgstr "användarnamn"
-
-#: contrib/auth/models.py:90
-msgid ""
-"Required. 30 characters or fewer. Alphanumeric characters only (letters, "
-"digits and underscores)."
-msgstr "Obligatorisk. 30 tecken eller mindre. Endast bokstäver, siffror eller understräck."
-
-#: contrib/auth/models.py:91
-msgid "first name"
-msgstr "förnamn"
-
-#: contrib/auth/models.py:92
-msgid "last name"
-msgstr "efternamn"
-
-#: contrib/auth/models.py:93
-msgid "e-mail address"
-msgstr "e-mailadress"
-
-#: contrib/auth/models.py:94
-msgid "password"
-msgstr "lösenord"
-
-#: contrib/auth/models.py:94
-msgid ""
-"Use '[algo]$[salt]$[hexdigest]' or use the <a href=\"password/\">change "
-"password form</a>."
-msgstr "Använd '[algo]$[salt]$[hexdigest]' eller använd <a href=\"password/\">Ändra lösenord</a>."
-
-#: contrib/auth/models.py:95
-msgid "staff status"
-msgstr "personalstatus"
-
-#: contrib/auth/models.py:95
-msgid "Designates whether the user can log into this admin site."
-msgstr "Avgör om användaren kan logga in på den här admin-siten."
-
-#: contrib/auth/models.py:96
-msgid "active"
-msgstr "aktiv"
-
-#: contrib/auth/models.py:96
-msgid ""
-"Designates whether this user can log into the Django admin. Unselect this "
-"instead of deleting accounts."
+#: contrib/humanize/templatetags/humanize.py:17
+msgid "th"
msgstr ""
-"Avgör om användaren kan logga in till Django admin. Av-markera denna "
-"istället för att ta bort konton."
-
-#: contrib/auth/models.py:97
-msgid "superuser status"
-msgstr "superanvändare"
-#: contrib/auth/models.py:97
-msgid ""
-"Designates that this user has all permissions without explicitly assigning "
-"them."
+#: contrib/humanize/templatetags/humanize.py:17
+msgid "st"
msgstr ""
-"Bestämmer att användaren har alla rättigheter utan att uttryckligen tilldela "
-"dem"
-#: contrib/auth/models.py:98
-msgid "last login"
-msgstr "senaste inloggning"
-
-#: contrib/auth/models.py:99
-msgid "date joined"
-msgstr "registreringsdatum"
+#: contrib/humanize/templatetags/humanize.py:17
+msgid "nd"
+msgstr ""
-#: contrib/auth/models.py:101
-msgid ""
-"In addition to the permissions manually assigned, this user will also get "
-"all permissions granted to each group he/she is in."
+#: contrib/humanize/templatetags/humanize.py:17
+msgid "rd"
msgstr ""
-"Förutom de rättigheterna som utdelas manuellt så kommer användaren dessutom "
-"få samma rättigheter som de grupper där han/hon är medlem."
-#: contrib/auth/models.py:102
-msgid "user permissions"
-msgstr "användarättigheter"
+#: contrib/humanize/templatetags/humanize.py:47
+#, python-format
+msgid "%(value).1f million"
+msgid_plural "%(value).1f million"
+msgstr[0] "%(value).1f miljon"
+msgstr[1] "%(value).1f miljoner"
-#: contrib/auth/models.py:105
-msgid "user"
-msgstr "användare"
+#: contrib/humanize/templatetags/humanize.py:50
+#, python-format
+#, fuzzy
+msgid "%(value).1f billion"
+msgid_plural "%(value).1f billion"
+msgstr[0] "%(value)1.f miljard"
+msgstr[1] "%(value)1.f miljarder"
-#: contrib/auth/models.py:106
-msgid "users"
-msgstr "användare"
+#: contrib/humanize/templatetags/humanize.py:53
+#, python-format
+#, fuzzy
+msgid "%(value).1f trillion"
+msgid_plural "%(value).1f trillion"
+msgstr[0] "%(value)1.f biljon"
+msgstr[1] "%(value)1.f biljoner"
-#: contrib/auth/models.py:111
-msgid "Personal info"
-msgstr "Personlig information"
+#: contrib/humanize/templatetags/humanize.py:68
+#, fuzzy
+msgid "one"
+msgstr "ett"
-#: contrib/auth/models.py:112
-msgid "Permissions"
-msgstr "Rättigheter"
+#: contrib/humanize/templatetags/humanize.py:68
+msgid "two"
+msgstr "två"
-#: contrib/auth/models.py:113
-msgid "Important dates"
-msgstr "Viktiga datum"
+#: contrib/humanize/templatetags/humanize.py:68
+msgid "three"
+msgstr "tre"
-#: contrib/auth/models.py:114
-msgid "Groups"
-msgstr "Grupper"
+#: contrib/humanize/templatetags/humanize.py:68
+msgid "four"
+msgstr "fyra"
-#: contrib/auth/models.py:258
-msgid "message"
-msgstr "meddelande"
+#: contrib/humanize/templatetags/humanize.py:68
+msgid "five"
+msgstr "fem"
-#: contrib/auth/forms.py:17 contrib/auth/forms.py:138
-msgid "The two password fields didn't match."
-msgstr "De båda lösenorden stämde inte överens."
+#: contrib/humanize/templatetags/humanize.py:68
+msgid "six"
+msgstr "sex"
-#: contrib/auth/forms.py:25
-msgid "A user with that username already exists."
-msgstr "En användare med det användarnamnet finns redan."
+#: contrib/humanize/templatetags/humanize.py:68
+msgid "seven"
+msgstr "sju"
-#: contrib/auth/forms.py:53
-msgid ""
-"Your Web browser doesn't appear to have cookies enabled. Cookies are "
-"required for logging in."
-msgstr ""
-"Din webläsare verkar inte stödja cookies. Cookie behövs för att kunna logga "
-"in."
-
-#: contrib/auth/forms.py:60 contrib/admin/views/decorators.py:10
-msgid ""
-"Please enter a correct username and password. Note that both fields are case-"
-"sensitive."
-msgstr ""
-"V.G. ange ett korrekt användarnamn och lösenord. Observera att båda fälten gör "
-"skillnad på versaler och gemener."
-
-#: contrib/auth/forms.py:62
-msgid "This account is inactive."
-msgstr "Detta konto är inaktivt."
-
-#: contrib/auth/forms.py:85
-msgid ""
-"That e-mail address doesn't have an associated user account. Are you sure "
-"you've registered?"
-msgstr ""
-"Den e-mailadressen har inte något konto associerat med sig. Är du säker på "
-"att du har registrerat dig?"
+#: contrib/humanize/templatetags/humanize.py:68
+msgid "eight"
+msgstr "åtta"
-#: contrib/auth/forms.py:117
-msgid "The two 'new password' fields didn't match."
-msgstr "De båda nya lösenordsfälten stämde inte överens."
-
-#: contrib/auth/forms.py:124
-msgid "Your old password was entered incorrectly. Please enter it again."
-msgstr "Ditt gamla lösenord var felaktigt ifyllt. Var vänlig fyll i det igen"
+#: contrib/humanize/templatetags/humanize.py:68
+msgid "nine"
+msgstr "nio"
#: contrib/redirects/models.py:7
msgid "redirect from"
@@ -867,8 +814,8 @@ msgid ""
"This can be either an absolute path (as above) or a full URL starting with "
"'http://'."
msgstr ""
-"Detta kan vara antingen en absolut sökväg (som ovan), eller en komplett "
-"URL som börjar med 'http://'."
+"Detta kan vara antingen en absolut sökväg (som ovan), eller en komplett URL "
+"som börjar med 'http://'."
#: contrib/redirects/models.py:13
msgid "redirect"
@@ -935,7 +882,7 @@ msgstr "datum/tid postat"
msgid "is public"
msgstr "är offentligt"
-#: contrib/comments/models.py:85 contrib/admin/views/doc.py:304
+#: contrib/comments/models.py:85 contrib/admin/views/doc.py:305
msgid "IP address"
msgstr "IP-adress"
@@ -1045,20 +992,20 @@ msgstr "Flaggad av %r"
#: contrib/comments/models.py:278
msgid "deletion date"
-msgstr "borttagnings-datum"
+msgstr "borttagningsdatum"
#: contrib/comments/models.py:280
msgid "moderator deletion"
-msgstr "moderator-borttagning"
+msgstr "moderatorborttagning"
#: contrib/comments/models.py:281
msgid "moderator deletions"
-msgstr "moderator-borttagningar"
+msgstr "moderatorborttagningar"
#: contrib/comments/models.py:285
#, python-format
msgid "Moderator deletion by %r"
-msgstr "Moderator-borttagning av %r"
+msgstr "Moderatorborttagning av %r"
#: contrib/comments/views/karma.py:19
msgid "Anonymous users cannot vote"
@@ -1066,14 +1013,15 @@ msgstr "Anonyma användare kan inte rösta"
#: contrib/comments/views/karma.py:23
msgid "Invalid comment ID"
-msgstr "Ogiltig kommentaridentifikation"
+msgstr "Ogiltig kommentarsidentifikation"
#: contrib/comments/views/karma.py:25
msgid "No voting for yourself"
msgstr "Du får inte rösta på dig själv"
#: contrib/comments/views/comments.py:27
-msgid "This rating is required because you've entered at least one other rating."
+msgid ""
+"This rating is required because you've entered at least one other rating."
msgstr "Det här betyget krävs eftersom du har fyllt i minst ett annat betyg."
#: contrib/comments/views/comments.py:111
@@ -1089,13 +1037,13 @@ msgid_plural ""
"\n"
"%(text)s"
msgstr[0] ""
-"Den här kommentaren postades av en användare som har postat mindre än "
-"%(count)s kommentar:\n"
+"Den här kommentaren postades av en användare som har postat mindre än %"
+"(count)s kommentar:\n"
"\n"
"%(text)s"
msgstr[1] ""
-"Den här kommentaren postades av en användare som har postat mindre än "
-"%(count)s kommentarer:\n"
+"Den här kommentaren postades av en användare som har postat mindre än %"
+"(count)s kommentarer:\n"
"\n"
"%(text)s"
@@ -1139,20 +1087,6 @@ msgstr ""
msgid "The comment form didn't provide either 'preview' or 'post'"
msgstr "Kommentars-formuläret skickade varken 'förhandsgranska' eller 'post'"
-#: contrib/comments/templates/comments/freeform.html:4
-msgid "Your name:"
-msgstr "Ditt namn:"
-
-#: contrib/comments/templates/comments/freeform.html:5
-#: contrib/comments/templates/comments/form.html:28
-msgid "Comment:"
-msgstr "Kommentar:"
-
-#: contrib/comments/templates/comments/freeform.html:10
-#: contrib/comments/templates/comments/form.html:35
-msgid "Preview comment"
-msgstr "Förhandsgranska kommentar"
-
#: contrib/comments/templates/comments/form.html:6
#: contrib/comments/templates/comments/form.html:8
#: contrib/admin/templates/admin/login.html:17
@@ -1160,24 +1094,24 @@ msgid "Username:"
msgstr "Användarnamn:"
#: contrib/comments/templates/comments/form.html:6
-#: contrib/admin/templates/admin/object_history.html:3
#: contrib/admin/templates/admin/change_list.html:5
+#: contrib/admin/templates/admin/object_history.html:3
#: contrib/admin/templates/admin/change_form.html:10
-#: contrib/admin/templates/admin/base.html:25
#: contrib/admin/templates/admin/delete_confirmation.html:3
+#: contrib/admin/templates/admin/base.html:25
#: contrib/admin/templates/admin/auth/user/change_password.html:9
#: contrib/admin/templates/registration/password_change_done.html:3
#: contrib/admin/templates/registration/password_change_form.html:3
-#: contrib/admin/templates/admin_doc/bookmarklets.html:4
#: contrib/admin/templates/admin_doc/view_detail.html:4
-#: contrib/admin/templates/admin_doc/template_tag_index.html:5
+#: contrib/admin/templates/admin_doc/bookmarklets.html:4
#: contrib/admin/templates/admin_doc/template_detail.html:4
-#: contrib/admin/templates/admin_doc/template_filter_index.html:5
+#: contrib/admin/templates/admin_doc/template_tag_index.html:5
#: contrib/admin/templates/admin_doc/missing_docutils.html:4
#: contrib/admin/templates/admin_doc/view_index.html:5
#: contrib/admin/templates/admin_doc/model_detail.html:3
#: contrib/admin/templates/admin_doc/index.html:4
#: contrib/admin/templates/admin_doc/model_index.html:5
+#: contrib/admin/templates/admin_doc/template_filter_index.html:5
msgid "Log out"
msgstr "Logga ut"
@@ -1208,73 +1142,19 @@ msgstr "Valfri"
msgid "Post a photo"
msgstr "Lägg till foto"
-#: contrib/flatpages/models.py:7 contrib/admin/views/doc.py:315
-msgid "URL"
-msgstr "URL"
-
-#: contrib/flatpages/models.py:8
-msgid "Example: '/about/contact/'. Make sure to have leading and trailing slashes."
-msgstr "Exempel: '/om/kontakt/'. Se till att ha inledande och avslutande snedsträck."
-
-#: contrib/flatpages/models.py:9
-msgid "title"
-msgstr "titel"
-
-#: contrib/flatpages/models.py:10
-msgid "content"
-msgstr "innehåll"
-
-#: contrib/flatpages/models.py:11
-msgid "enable comments"
-msgstr "aktivera kommentarer"
-
-#: contrib/flatpages/models.py:12
-msgid "template name"
-msgstr "mallnamn"
-
-#: contrib/flatpages/models.py:13
-msgid ""
-"Example: 'flatpages/contact_page.html'. If this isn't provided, the system "
-"will use 'flatpages/default.html'."
-msgstr ""
-"Exempel: 'sidor/kontaktsida.html'. Om det här inte fylls i kommer systemet "
-"att använda 'sidor/default.html'."
-
-#: contrib/flatpages/models.py:14
-msgid "registration required"
-msgstr "registrering krävs"
-
-#: contrib/flatpages/models.py:14
-msgid "If this is checked, only logged-in users will be able to view the page."
-msgstr "Om det här bockas i kommer endast inloggade användare att kunna visa sidan"
-
-#: contrib/flatpages/models.py:18
-msgid "flat page"
-msgstr "flatsida"
-
-#: contrib/flatpages/models.py:19
-msgid "flat pages"
-msgstr "flatsidor"
-
-#: contrib/sessions/models.py:51
-msgid "session key"
-msgstr "sessionsnyckel"
-
-#: contrib/sessions/models.py:52
-msgid "session data"
-msgstr "sessionsdata"
-
-#: contrib/sessions/models.py:53
-msgid "expire date"
-msgstr "utgångsdatum"
+#: contrib/comments/templates/comments/form.html:28
+#: contrib/comments/templates/comments/freeform.html:5
+msgid "Comment:"
+msgstr "Kommentar:"
-#: contrib/sessions/models.py:57
-msgid "session"
-msgstr "session"
+#: contrib/comments/templates/comments/form.html:35
+#: contrib/comments/templates/comments/freeform.html:10
+msgid "Preview comment"
+msgstr "Förhandsgranska kommentar"
-#: contrib/sessions/models.py:58
-msgid "sessions"
-msgstr "sessioner"
+#: contrib/comments/templates/comments/freeform.html:4
+msgid "Your name:"
+msgstr "Ditt namn:"
#: contrib/sites/models.py:10
msgid "domain name"
@@ -1354,49 +1234,19 @@ msgstr "loggpost"
msgid "log entries"
msgstr "loggposter"
-#: contrib/admin/templatetags/admin_list.py:247
+#: contrib/admin/templatetags/admin_list.py:249
msgid "All dates"
msgstr "Alla datum"
-#: contrib/admin/views/decorators.py:24
-#: contrib/admin/templates/admin/login.html:25
-msgid "Log in"
-msgstr "Logga in"
-
-#: contrib/admin/views/decorators.py:62
-msgid ""
-"Please log in again, because your session has expired. Don't worry: Your "
-"submission has been saved."
-msgstr ""
-"V.G. logga in igen, eftersom din session har tagit slut. Oroa dig inte: ditt "
-"bidrag har sparats."
-
-#: contrib/admin/views/decorators.py:69
-msgid ""
-"Looks like your browser isn't configured to accept cookies. Please enable "
-"cookies, reload this page, and try again."
-msgstr ""
-"Det ser ut som om din webläsare inte är konfigurerad att acceptera cookies. "
-"Aktivera cookies, ladda om den här sidan, och försök igen."
-
-#: contrib/admin/views/decorators.py:83
-msgid "Usernames cannot contain the '@' character."
-msgstr "Användarnamn kan inte innehålla tecknet '@'."
-
-#: contrib/admin/views/decorators.py:85
-#, python-format
-msgid "Your e-mail address is not your username. Try '%s' instead."
-msgstr "Din e-mailadress är inte ditt användarnamn. Försök med '%s' istället."
-
#: contrib/admin/views/auth.py:19 contrib/admin/views/main.py:257
#, python-format
msgid "The %(name)s \"%(obj)s\" was added successfully."
-msgstr "%(name)set \"%(obj)s\" lades till."
+msgstr "%(name)s \"%(obj)s\" lades till."
#: contrib/admin/views/auth.py:24 contrib/admin/views/main.py:261
#: contrib/admin/views/main.py:347
msgid "You may edit it again below."
-msgstr "Du kan ändra det igen här under."
+msgstr "Du kan ändra det igen nedanför."
#: contrib/admin/views/auth.py:30
msgid "Add user"
@@ -1413,12 +1263,12 @@ msgstr "Ändra lösenord: %s"
#: contrib/admin/views/main.py:223
msgid "Site administration"
-msgstr "Administration"
+msgstr "Site-administration"
#: contrib/admin/views/main.py:271 contrib/admin/views/main.py:356
#, python-format
msgid "You may add another %s below."
-msgstr "Du kan lägga till en till %s här under."
+msgstr "Du kan lägga till en till %s nedanför."
#: contrib/admin/views/main.py:289
#, python-format
@@ -1447,12 +1297,13 @@ msgstr "Inga fält ändrade."
#: contrib/admin/views/main.py:345
#, python-format
msgid "The %(name)s \"%(obj)s\" was changed successfully."
-msgstr "%(name)set \"%(obj)s\" ändrades."
+msgstr "%(name)s \"%(obj)s\" ändrades."
#: contrib/admin/views/main.py:353
#, python-format
-msgid "The %(name)s \"%(obj)s\" was added successfully. You may edit it again below."
-msgstr "%(name)set \"%(obj)s\" lades till. Du kan ändra det igen här under."
+msgid ""
+"The %(name)s \"%(obj)s\" was added successfully. You may edit it again below."
+msgstr "%(name)s \"%(obj)s\" lades till. Du kan ändra det igen nedanför."
#: contrib/admin/views/main.py:391
#, python-format
@@ -1481,7 +1332,7 @@ msgstr "Är du säker?"
#: contrib/admin/views/main.py:539
#, python-format
msgid "Change history: %s"
-msgstr "Ändra historien: %s"
+msgstr "Ändra historik: %s"
#: contrib/admin/views/main.py:573
#, python-format
@@ -1495,7 +1346,45 @@ msgstr "Välj %s att ändra"
#: contrib/admin/views/main.py:768
msgid "Database error"
-msgstr "Databas fel"
+msgstr "Databasfel"
+
+#: contrib/admin/views/decorators.py:10 contrib/auth/forms.py:60
+msgid ""
+"Please enter a correct username and password. Note that both fields are case-"
+"sensitive."
+msgstr ""
+"Var god ange ett korrekt användarnamn och lösenord. Observera att båda "
+"fälten är skiftlägeskänsliga."
+
+#: contrib/admin/views/decorators.py:24
+#: contrib/admin/templates/admin/login.html:25
+msgid "Log in"
+msgstr "Logga in"
+
+#: contrib/admin/views/decorators.py:62
+msgid ""
+"Please log in again, because your session has expired. Don't worry: Your "
+"submission has been saved."
+msgstr ""
+"Var god logga in igen, eftersom din session har tagit slut. "
+"Oroa dig inte: Ditt bidrag har sparats."
+
+#: contrib/admin/views/decorators.py:69
+msgid ""
+"Looks like your browser isn't configured to accept cookies. Please enable "
+"cookies, reload this page, and try again."
+msgstr ""
+"Det ser ut som om din webläsare inte är konfigurerad att acceptera cookies. "
+"Aktivera cookies, ladda om den här sidan, och försök igen."
+
+#: contrib/admin/views/decorators.py:83
+msgid "Usernames cannot contain the '@' character."
+msgstr "Användarnamn kan inte innehålla '@' tecknet."
+
+#: contrib/admin/views/decorators.py:85
+#, python-format
+msgid "Your e-mail address is not your username. Try '%s' instead."
+msgstr "Din e-mailadress är inte ditt användarnamn. Försök med '%s' istället."
#: contrib/admin/views/doc.py:46 contrib/admin/views/doc.py:48
#: contrib/admin/views/doc.py:50
@@ -1510,7 +1399,7 @@ msgstr "filter:"
#: contrib/admin/views/doc.py:135 contrib/admin/views/doc.py:137
#: contrib/admin/views/doc.py:139
msgid "view:"
-msgstr "Vy:"
+msgstr "vy:"
#: contrib/admin/views/doc.py:164
#, python-format
@@ -1518,14 +1407,14 @@ msgid "App %r not found"
msgstr "Applikation %r hittades inte"
#: contrib/admin/views/doc.py:171
-#, python-format
-msgid "Model %(model_name)r not found in app %(app_label)r"
+#, fuzzy, python-format
+msgid "Model %(name)r not found in app %(label)r"
msgstr "Modellen %(model_name)r hittades inte i applikation %(app_label)r"
#: contrib/admin/views/doc.py:183
-#, python-format
-msgid "the related `%(app_label)s.%(data_type)s` object"
-msgstr "Det sammalänkade `%(app_label)s.%(data_type)s` objektet"
+#, fuzzy, python-format
+msgid "the related `%(label)s.%(type)s` object"
+msgstr "det relaterade `%(app_label)s.%(data_type)s` objektet"
#: contrib/admin/views/doc.py:183 contrib/admin/views/doc.py:205
#: contrib/admin/views/doc.py:219 contrib/admin/views/doc.py:224
@@ -1533,9 +1422,9 @@ msgid "model:"
msgstr "modell:"
#: contrib/admin/views/doc.py:214
-#, python-format
-msgid "related `%(app_label)s.%(object_name)s` objects"
-msgstr "sammanlänkade `%(app_label)s.%(object_name)s` objekt"
+#, fuzzy, python-format
+msgid "related `%(label)s.%(name)s` objects"
+msgstr "relaterade `%(app_label)s.%(object_name)s` objekt"
#: contrib/admin/views/doc.py:219
#, python-format
@@ -1552,17 +1441,17 @@ msgstr "antal %s"
msgid "Fields on %s objects"
msgstr "Fält på %s objekt"
-#: contrib/admin/views/doc.py:291 contrib/admin/views/doc.py:301
-#: contrib/admin/views/doc.py:303 contrib/admin/views/doc.py:309
-#: contrib/admin/views/doc.py:310 contrib/admin/views/doc.py:312
+#: contrib/admin/views/doc.py:291 contrib/admin/views/doc.py:302
+#: contrib/admin/views/doc.py:304 contrib/admin/views/doc.py:310
+#: contrib/admin/views/doc.py:311 contrib/admin/views/doc.py:313
msgid "Integer"
msgstr "Heltal"
#: contrib/admin/views/doc.py:292
msgid "Boolean (Either True or False)"
-msgstr "Boolesk (antingen Sann eller Falsk)"
+msgstr "Boolesk (antingen True eller False)"
-#: contrib/admin/views/doc.py:293 contrib/admin/views/doc.py:311
+#: contrib/admin/views/doc.py:293 contrib/admin/views/doc.py:312
#, python-format
msgid "String (up to %(maxlength)s)"
msgstr "Sträng (upp till %(maxlength)s)"
@@ -1580,50 +1469,58 @@ msgid "Date (with time)"
msgstr "Datum (med tid)"
#: contrib/admin/views/doc.py:297
+msgid "Decimal number"
+msgstr "Decimaltal"
+
+#: contrib/admin/views/doc.py:298
msgid "E-mail address"
msgstr "E-postadress:"
-#: contrib/admin/views/doc.py:298 contrib/admin/views/doc.py:299
-#: contrib/admin/views/doc.py:302
+#: contrib/admin/views/doc.py:299 contrib/admin/views/doc.py:300
+#: contrib/admin/views/doc.py:303
msgid "File path"
-msgstr "Sökväg"
+msgstr "Filsökväg"
-#: contrib/admin/views/doc.py:300
-msgid "Decimal number"
-msgstr "Decimaltal"
+#: contrib/admin/views/doc.py:301
+msgid "Floating point number"
+msgstr "Flyttal"
-#: contrib/admin/views/doc.py:306
+#: contrib/admin/views/doc.py:307
msgid "Boolean (Either True, False or None)"
msgstr "Boolesk (antingen True, False eller None)"
-#: contrib/admin/views/doc.py:307
+#: contrib/admin/views/doc.py:308
msgid "Relation to parent model"
msgstr "Relation till förälder-modell"
-#: contrib/admin/views/doc.py:308
+#: contrib/admin/views/doc.py:309
msgid "Phone number"
msgstr "Telefonnummer"
-#: contrib/admin/views/doc.py:313
+#: contrib/admin/views/doc.py:314
msgid "Text"
msgstr "Text"
-#: contrib/admin/views/doc.py:314
+#: contrib/admin/views/doc.py:315
msgid "Time"
msgstr "Tid"
-#: contrib/admin/views/doc.py:316
+#: contrib/admin/views/doc.py:316 contrib/flatpages/models.py:7
+msgid "URL"
+msgstr "URL"
+
+#: contrib/admin/views/doc.py:317
msgid "U.S. state (two uppercase letters)"
msgstr "Stat i USA (två versaler)"
-#: contrib/admin/views/doc.py:317
+#: contrib/admin/views/doc.py:318
msgid "XML text"
msgstr "XML-text"
-#: contrib/admin/views/doc.py:343
+#: contrib/admin/views/doc.py:344
#, python-format
msgid "%s does not appear to be a urlpattern object"
-msgstr "%s verkar inte vara ett urlmönster-objekt"
+msgstr "%s verkar inte vara ett urlpattern-objekt"
#: contrib/admin/templates/widget/file.html:2
msgid "Currently:"
@@ -1641,11 +1538,11 @@ msgstr "Datum:"
msgid "Time:"
msgstr "Tid:"
-#: contrib/admin/templates/admin/object_history.html:3
#: contrib/admin/templates/admin/change_list.html:5
+#: contrib/admin/templates/admin/object_history.html:3
#: contrib/admin/templates/admin/change_form.html:10
-#: contrib/admin/templates/admin/base.html:25
#: contrib/admin/templates/admin/delete_confirmation.html:3
+#: contrib/admin/templates/admin/base.html:25
#: contrib/admin/templates/admin/auth/user/change_password.html:9
#: contrib/admin/templates/registration/password_change_done.html:3
#: contrib/admin/templates/registration/password_change_form.html:3
@@ -1653,36 +1550,36 @@ msgstr "Tid:"
msgid "Documentation"
msgstr "Dokumentation"
-#: contrib/admin/templates/admin/object_history.html:3
#: contrib/admin/templates/admin/change_list.html:5
+#: contrib/admin/templates/admin/object_history.html:3
#: contrib/admin/templates/admin/change_form.html:10
-#: contrib/admin/templates/admin/base.html:25
#: contrib/admin/templates/admin/delete_confirmation.html:3
+#: contrib/admin/templates/admin/base.html:25
#: contrib/admin/templates/admin/auth/user/change_password.html:9
#: contrib/admin/templates/admin/auth/user/change_password.html:15
#: contrib/admin/templates/admin/auth/user/change_password.html:46
#: contrib/admin/templates/registration/password_change_done.html:3
#: contrib/admin/templates/registration/password_change_form.html:3
-#: contrib/admin/templates/admin_doc/bookmarklets.html:4
#: contrib/admin/templates/admin_doc/view_detail.html:4
-#: contrib/admin/templates/admin_doc/template_tag_index.html:5
+#: contrib/admin/templates/admin_doc/bookmarklets.html:4
#: contrib/admin/templates/admin_doc/template_detail.html:4
-#: contrib/admin/templates/admin_doc/template_filter_index.html:5
+#: contrib/admin/templates/admin_doc/template_tag_index.html:5
#: contrib/admin/templates/admin_doc/missing_docutils.html:4
#: contrib/admin/templates/admin_doc/view_index.html:5
#: contrib/admin/templates/admin_doc/model_detail.html:3
#: contrib/admin/templates/admin_doc/index.html:4
#: contrib/admin/templates/admin_doc/model_index.html:5
+#: contrib/admin/templates/admin_doc/template_filter_index.html:5
msgid "Change password"
msgstr "Ändra lösenord"
-#: contrib/admin/templates/admin/object_history.html:5
#: contrib/admin/templates/admin/change_list.html:6
+#: contrib/admin/templates/admin/object_history.html:5
#: contrib/admin/templates/admin/500.html:4
#: contrib/admin/templates/admin/invalid_setup.html:4
#: contrib/admin/templates/admin/change_form.html:13
-#: contrib/admin/templates/admin/base.html:30
#: contrib/admin/templates/admin/delete_confirmation.html:6
+#: contrib/admin/templates/admin/base.html:30
#: contrib/admin/templates/admin/auth/user/change_password.html:12
#: contrib/admin/templates/registration/password_change_done.html:4
#: contrib/admin/templates/registration/password_reset_form.html:4
@@ -1693,6 +1590,16 @@ msgstr "Ändra lösenord"
msgid "Home"
msgstr "Hem"
+#: contrib/admin/templates/admin/change_list.html:12
+#, python-format
+msgid "Add %(name)s"
+msgstr "Lägg till %(name)s"
+
+#: contrib/admin/templates/admin/filter.html:2
+#, python-format
+msgid " By %(filter_title)s "
+msgstr " Av %(filter_title)s "
+
#: contrib/admin/templates/admin/object_history.html:5
#: contrib/admin/templates/admin/change_form.html:21
msgid "History"
@@ -1720,50 +1627,11 @@ msgid ""
"admin site."
msgstr ""
"Det här objektet har ingen ändringshistorik. Det lades antagligen inte till "
-"i den här admin-siten"
-
-#: contrib/admin/templates/admin/change_list.html:12
-#, python-format
-msgid "Add %(name)s"
-msgstr "Lägg till %(name)s"
-
-#: contrib/admin/templates/admin/filter.html:2
-#, python-format
-msgid " By %(filter_title)s "
-msgstr " Av %(filter_title)s "
-
-#: contrib/admin/templates/admin/500.html:4
-msgid "Server error"
-msgstr "Serverfel"
-
-#: contrib/admin/templates/admin/500.html:6
-msgid "Server error (500)"
-msgstr "Serverfel (500)"
-
-#: contrib/admin/templates/admin/500.html:9
-msgid "Server Error <em>(500)</em>"
-msgstr "Serverfel <em>(500)</em>"
-
-#: contrib/admin/templates/admin/500.html:10
-msgid ""
-"There's been an error. It's been reported to the site administrators via e-"
-"mail and should be fixed shortly. Thanks for your patience."
-msgstr ""
-"Ett fel har uppstått. Administratören har meddelats via e-mail och "
-"felet bör åtgärdas snart. Tack för ditt tålamod."
-
-#: contrib/admin/templates/admin/invalid_setup.html:8
-msgid ""
-"Something's wrong with your database installation. Make sure the appropriate "
-"database tables have been created, and make sure the database is readable by "
-"the appropriate user."
-msgstr ""
-"Någonting är fel med din databasinstallation. Se till att de rätta tabellerna har "
-"skapats och att databasen är läsbar av rätt användare."
+"via denna administrationssite."
#: contrib/admin/templates/admin/search_form.html:8
msgid "Go"
-msgstr "Utför"
+msgstr "Kör"
#: contrib/admin/templates/admin/search_form.html:10
#, python-format
@@ -1789,18 +1657,34 @@ msgstr "Django site-administration"
msgid "Django administration"
msgstr "Django administration"
-#: contrib/admin/templates/admin/filters.html:4
-msgid "Filter"
-msgstr "Filter"
+#: contrib/admin/templates/admin/500.html:4
+msgid "Server error"
+msgstr "Serverfel"
-#: contrib/admin/templates/admin/404.html:4
-#: contrib/admin/templates/admin/404.html:8
-msgid "Page not found"
-msgstr "Sidan kunde inte hittas"
+#: contrib/admin/templates/admin/500.html:6
+msgid "Server error (500)"
+msgstr "Serverfel (500)"
-#: contrib/admin/templates/admin/404.html:10
-msgid "We're sorry, but the requested page could not be found."
-msgstr "Vi är ledsna, men den efterfrågade sidan kunde inte hittas."
+#: contrib/admin/templates/admin/500.html:9
+msgid "Server Error <em>(500)</em>"
+msgstr "Serverfel <em>(500)</em>"
+
+#: contrib/admin/templates/admin/500.html:10
+msgid ""
+"There's been an error. It's been reported to the site administrators via e-"
+"mail and should be fixed shortly. Thanks for your patience."
+msgstr ""
+"Ett fel har uppstått. Administratören har meddelats via e-mail och felet bör "
+"åtgärdas snart. Tack för ditt tålamod."
+
+#: contrib/admin/templates/admin/invalid_setup.html:8
+msgid ""
+"Something's wrong with your database installation. Make sure the appropriate "
+"database tables have been created, and make sure the database is readable by "
+"the appropriate user."
+msgstr ""
+"Någonting är fel med din databasinstallation. Se till att de rätta "
+"tabellerna har skapats och att databasen är läsbar av rätt användare."
#: contrib/admin/templates/admin/index.html:17
#, python-format
@@ -1814,6 +1698,7 @@ msgstr "%(name)s"
#: contrib/admin/templates/admin/index.html:28
#: contrib/admin/templates/admin/change_form.html:15
+#, fuzzy
msgid "Add"
msgstr "Lägg&nbsp;till"
@@ -1837,9 +1722,22 @@ msgstr "Mina Händelser"
msgid "None available"
msgstr "Inga tillgängliga"
+#: contrib/admin/templates/admin/404.html:4
+#: contrib/admin/templates/admin/404.html:8
+msgid "Page not found"
+msgstr "Sidan kunde inte hittas"
+
+#: contrib/admin/templates/admin/404.html:10
+msgid "We're sorry, but the requested page could not be found."
+msgstr "Vi är ledsna, men den efterfrågade sidan kunde inte hittas."
+
+#: contrib/admin/templates/admin/filters.html:4
+msgid "Filter"
+msgstr "Filter"
+
#: contrib/admin/templates/admin/change_form.html:22
msgid "View on site"
-msgstr "Visa på siten"
+msgstr "Visa på site"
#: contrib/admin/templates/admin/change_form.html:32
#: contrib/admin/templates/admin/auth/user/change_password.html:24
@@ -1856,10 +1754,6 @@ msgstr "Sortering"
msgid "Order:"
msgstr "Sortera:"
-#: contrib/admin/templates/admin/base.html:25
-msgid "Welcome,"
-msgstr "Välkommen,"
-
#: contrib/admin/templates/admin/delete_confirmation.html:9
#: contrib/admin/templates/admin/submit_line.html:3
msgid "Delete"
@@ -1872,9 +1766,9 @@ msgid ""
"related objects, but your account doesn't have permission to delete the "
"following types of objects:"
msgstr ""
-"Att ta bort %(object_name)s '%(escaped_object)s' skulle innebära att besläktade "
-"objekt togs bort, men ditt konto har inte rättigheter att ta bort följande "
-"objekttyper:"
+"Att ta bort %(object_name)s '%(escaped_object)s' skulle innebära att "
+"besläktade objekt togs bort, men ditt konto har inte rättigheter att ta bort "
+"följande objekttyper:"
#: contrib/admin/templates/admin/delete_confirmation.html:21
#, python-format
@@ -1882,13 +1776,17 @@ msgid ""
"Are you sure you want to delete the %(object_name)s \"%(escaped_object)s\"? "
"All of the following related items will be deleted:"
msgstr ""
-"Är du säker på att du vill ta bort %(object_name)s \"%(escaped_object)s\"? Alla "
-"dessa sammanlänkade objekt kommer att tas bort:"
+"Är du säker på att du vill ta bort %(object_name)s \"%(escaped_object)s\"? "
+"Alla dessa sammanlänkade objekt kommer att tas bort:"
#: contrib/admin/templates/admin/delete_confirmation.html:26
msgid "Yes, I'm sure"
msgstr "Ja, jag är säker"
+#: contrib/admin/templates/admin/base.html:25
+msgid "Welcome,"
+msgstr "Välkommen,"
+
#: contrib/admin/templates/admin/submit_line.html:4
msgid "Save as new"
msgstr "Spara som ny"
@@ -1930,8 +1828,8 @@ msgid ""
"First, enter a username and password. Then, you'll be able to edit more user "
"options."
msgstr ""
-"Ange först ett användarnamn och ett lösenord. Sedan kommer du att kunna ändra "
-"fler användaralternativ."
+"Ange först ett användarnamn och ett lösenord. Sedan kommer du att kunna "
+"ändra fler användaralternativ."
#: contrib/admin/templates/admin/auth/user/add_form.html:12
msgid "Username"
@@ -1958,7 +1856,7 @@ msgstr "Ditt lösenord har ändrats."
#: contrib/admin/templates/registration/password_reset_form.html:10
#: contrib/admin/templates/registration/password_reset_done.html:4
msgid "Password reset"
-msgstr "Nollställ lösenordet"
+msgstr "Nollställ lösenord"
#: contrib/admin/templates/registration/password_reset_form.html:12
msgid ""
@@ -1987,7 +1885,7 @@ msgstr "Logga in igen"
#: contrib/admin/templates/registration/password_reset_done.html:6
#: contrib/admin/templates/registration/password_reset_done.html:10
msgid "Password reset successful"
-msgstr "Nollställning av lösenordet lyckades"
+msgstr "Lösenordsnollställning lyckades."
#: contrib/admin/templates/registration/password_reset_done.html:12
msgid ""
@@ -2052,7 +1950,7 @@ msgstr "Tack för att du använder vår site!"
#: contrib/admin/templates/registration/password_reset_email.html:15
#, python-format
msgid "The %(site_name)s team"
-msgstr "%(site_name)s-laget"
+msgstr "%(site_name)s-teamet"
#: contrib/admin/templates/admin_doc/bookmarklets.html:3
msgid "Bookmarklets"
@@ -2076,7 +1974,8 @@ msgstr ""
"<p class=\"help\">För att installera smarta bokmärken, dra länken till din\n"
"verktygsrad med bokmärken, eller högerklicka på länken och lägg till den\n"
"till dina bokmärken. Nu kan du välja det smarta bokmärket från alla sidor\n"
-"på siten. Observera att några av dessa smarta bokmärken kräver att du besöker\n"
+"på siten. Observera att några av dessa smarta bokmärken kräver att du "
+"besöker\n"
"sidan från en dator som är \"intern\" (tala med din systemadministratör\n"
"om du inte är säker på om din dator är \"intern\").</p>\n"
@@ -2122,14 +2021,737 @@ msgstr "Redigera det här objektet (nytt fönster)"
msgid "As above, but opens the admin page in a new window."
msgstr "Som ovan, men öppnar administrationssidan i ett nytt fönster."
+#: contrib/contenttypes/models.py:36
+msgid "python model class name"
+msgstr "python modell klassnamn"
+
+#: contrib/contenttypes/models.py:39
+msgid "content type"
+msgstr "innehållstyp"
+
+#: contrib/contenttypes/models.py:40
+msgid "content types"
+msgstr "innehållstyper"
+
+#: contrib/auth/views.py:40
+msgid "Logged out"
+msgstr "Utloggad"
+
+#: contrib/auth/models.py:44 contrib/auth/models.py:64
+msgid "name"
+msgstr "namn"
+
+#: contrib/auth/models.py:46
+msgid "codename"
+msgstr "kodnamn"
+
+#: contrib/auth/models.py:49
+msgid "permission"
+msgstr "rättighet"
+
+#: contrib/auth/models.py:50 contrib/auth/models.py:65
+msgid "permissions"
+msgstr "rättigheter"
+
+#: contrib/auth/models.py:68
+msgid "group"
+msgstr "grupp"
+
+#: contrib/auth/models.py:69 contrib/auth/models.py:109
+msgid "groups"
+msgstr "grupper"
+
+#: contrib/auth/models.py:99
+msgid "username"
+msgstr "användarnamn"
+
+#: contrib/auth/models.py:99
+msgid ""
+"Required. 30 characters or fewer. Alphanumeric characters only (letters, "
+"digits and underscores)."
+msgstr ""
+"Obligatorisk. 30 tecken eller mindre. Endast bokstäver, siffror eller "
+"understräck."
+
+#: contrib/auth/models.py:100
+msgid "first name"
+msgstr "förnamn"
+
+#: contrib/auth/models.py:101
+msgid "last name"
+msgstr "efternamn"
+
+#: contrib/auth/models.py:102
+msgid "e-mail address"
+msgstr "e-mailadress"
+
+#: contrib/auth/models.py:103
+msgid "password"
+msgstr "lösenord"
+
+#: contrib/auth/models.py:103
+msgid ""
+"Use '[algo]$[salt]$[hexdigest]' or use the <a href=\"password/\">change "
+"password form</a>."
+msgstr ""
+"Använd '[algo]$[salt]$[hexdigest]' eller använd <a href=\"password/\">Ändra "
+"lösenord</a>."
+
+#: contrib/auth/models.py:104
+msgid "staff status"
+msgstr "personalstatus"
+
+#: contrib/auth/models.py:104
+msgid "Designates whether the user can log into this admin site."
+msgstr "Avgör om användaren kan logga in på den här admin-siten."
+
+#: contrib/auth/models.py:105
+msgid "active"
+msgstr "aktiv"
+
+#: contrib/auth/models.py:105
+msgid ""
+"Designates whether this user can log into the Django admin. Unselect this "
+"instead of deleting accounts."
+msgstr ""
+"Avgör om användaren kan logga in till Django admin. Avmarkera denna "
+"istället för att ta bort konton."
+
+#: contrib/auth/models.py:106
+msgid "superuser status"
+msgstr "superanvändare"
+
+#: contrib/auth/models.py:106
+msgid ""
+"Designates that this user has all permissions without explicitly assigning "
+"them."
+msgstr ""
+"Avgör om användaren har alla rättigheter utan att uttryckligen tilldela "
+"dem"
+
+#: contrib/auth/models.py:107
+msgid "last login"
+msgstr "senaste inloggning"
+
+#: contrib/auth/models.py:108
+msgid "date joined"
+msgstr "registreringsdatum"
+
+#: contrib/auth/models.py:110
+msgid ""
+"In addition to the permissions manually assigned, this user will also get "
+"all permissions granted to each group he/she is in."
+msgstr ""
+"Förutom de rättigheterna som utdelas manuellt så kommer användaren dessutom "
+"få samma rättigheter som de grupper där han/hon är medlem."
+
+#: contrib/auth/models.py:111
+msgid "user permissions"
+msgstr "användarättigheter"
+
+#: contrib/auth/models.py:115
+msgid "user"
+msgstr "användare"
+
+#: contrib/auth/models.py:116
+msgid "users"
+msgstr "användare"
+
+#: contrib/auth/models.py:122
+msgid "Personal info"
+msgstr "Personlig information"
+
+#: contrib/auth/models.py:123
+msgid "Permissions"
+msgstr "Rättigheter"
+
+#: contrib/auth/models.py:124
+msgid "Important dates"
+msgstr "Viktiga datum"
+
+#: contrib/auth/models.py:125
+msgid "Groups"
+msgstr "Grupper"
+
+#: contrib/auth/models.py:269
+msgid "message"
+msgstr "meddelande"
+
+#: contrib/auth/models.py:282
+#, fuzzy
+msgid "AnonymousUser"
+msgstr "Anonym användare"
+
+#: contrib/auth/forms.py:17 contrib/auth/forms.py:138
+msgid "The two password fields didn't match."
+msgstr "De båda lösenorden stämde inte överens."
+
+#: contrib/auth/forms.py:25
+msgid "A user with that username already exists."
+msgstr "En användare med det användarnamnet finns redan."
+
+#: contrib/auth/forms.py:53
+msgid ""
+"Your Web browser doesn't appear to have cookies enabled. Cookies are "
+"required for logging in."
+msgstr ""
+"Din webläsare verkar inte stödja cookies. Cookie behövs för att kunna logga "
+"in."
+
+#: contrib/auth/forms.py:62
+msgid "This account is inactive."
+msgstr "Detta konto är inaktivt."
+
+#: contrib/auth/forms.py:85
+msgid ""
+"That e-mail address doesn't have an associated user account. Are you sure "
+"you've registered?"
+msgstr ""
+"Den e-mailadressen har inte något konto associerat med sig. Är du säker på "
+"att du har registrerat dig?"
+
+#: contrib/auth/forms.py:117
+msgid "The two 'new password' fields didn't match."
+msgstr "De två lösenordsfälten stämde inte överens."
+
+#: contrib/auth/forms.py:124
+msgid "Your old password was entered incorrectly. Please enter it again."
+msgstr "Ditt gamla lösenord var felaktigt ifyllt. Var vänlig fyll i det igen"
+
#: contrib/localflavor/uk/forms.py:18
msgid "Enter a postcode. A space is required between the two postcode parts."
msgstr "Fyll i ett postnummer. Du måste ha mellanslag mellan nummerdelarna."
-#: contrib/localflavor/usa/forms.py:17
+#: contrib/localflavor/au/forms.py:18
+msgid "Enter a 4 digit post code."
+msgstr "Fyll i en fyra-sifrigt postkod."
+
+#: contrib/localflavor/br/forms.py:18
+msgid "Enter a zip code in the format XXXXX-XXX."
+msgstr "Fyll i zipkod i XXXXX-XXX format."
+
+#: contrib/localflavor/br/forms.py:30
+msgid "Phone numbers must be in XX-XXXX-XXXX format."
+msgstr "Telefonnummer måste vara i det amerikanska formatet XX-XXXX-XXXX."
+
+#: contrib/localflavor/br/forms.py:72
+msgid "This field requires only numbers."
+msgstr "Detta fält kräver enbart siffror."
+
+#: contrib/localflavor/br/forms.py:74
+msgid "This field requires at most 11 digits or 14 characters."
+msgstr "Detta fält kräver högst 11 siffror eller 14 bokstäver."
+
+#: contrib/localflavor/br/forms.py:84
+msgid "Invalid CPF number."
+msgstr "Ogiltigt CPF-nummer."
+
+#: contrib/localflavor/br/forms.py:106
+msgid "This field requires at least 14 digits"
+msgstr "Detta fält kräver minst 14 sifrror"
+
+#: contrib/localflavor/br/forms.py:116
+msgid "Invalid CNPJ number."
+msgstr "Ogiltigt CNPJ-nummer."
+
+#: contrib/localflavor/fr/forms.py:17 contrib/localflavor/de/forms.py:16
+#: contrib/localflavor/fi/forms.py:14
+msgid "Enter a zip code in the format XXXXX."
+msgstr "Fyll i en zipkod i XXXXX format."
+
+#: contrib/localflavor/de/de_states.py:5
+msgid "Baden-Wuerttemberg"
+msgstr ""
+
+#: contrib/localflavor/de/de_states.py:6
+msgid "Bavaria"
+msgstr "Bayern"
+
+#: contrib/localflavor/de/de_states.py:7
+msgid "Berlin"
+msgstr "Berlin"
+
+#: contrib/localflavor/de/de_states.py:8
+msgid "Brandenburg"
+msgstr "Brandenburg"
+
+#: contrib/localflavor/de/de_states.py:9
+msgid "Bremen"
+msgstr "Bremen"
+
+#: contrib/localflavor/de/de_states.py:10
+msgid "Hamburg"
+msgstr "Hamburg"
+
+#: contrib/localflavor/de/de_states.py:11
+msgid "Hessen"
+msgstr "Hessen"
+
+#: contrib/localflavor/de/de_states.py:12
+msgid "Mecklenburg-Western Pomerania"
+msgstr "Mecklenburg-Vorpommern"
+
+#: contrib/localflavor/de/de_states.py:13
+msgid "Lower Saxony"
+msgstr "Nedre Sachsen"
+
+#: contrib/localflavor/de/de_states.py:14
+#, fuzzy
+msgid "North Rhine-Westphalia"
+msgstr "Norra Rhen-Westphalia"
+
+#: contrib/localflavor/de/de_states.py:15
+msgid "Rhineland-Palatinate"
+msgstr "Rhenlandet"
+
+#: contrib/localflavor/de/de_states.py:16
+msgid "Saarland"
+msgstr "Saarland"
+
+#: contrib/localflavor/de/de_states.py:17
+msgid "Saxony"
+msgstr "Sachsen"
+
+#: contrib/localflavor/de/de_states.py:18
+msgid "Saxony-Anhalt"
+msgstr "Sachsen-Anhalt"
+
+#: contrib/localflavor/de/de_states.py:19
+msgid "Schleswig-Holstein"
+msgstr ""
+
+#: contrib/localflavor/de/de_states.py:20
+msgid "Thuringia"
+msgstr ""
+
+#: contrib/localflavor/de/forms.py:60
+msgid ""
+"Enter a valid German identity card number in XXXXXXXXXXX-XXXXXXX-XXXXXXX-X "
+"format."
+msgstr ""
+"Fyll i ett giltigt tyskt ID-kortnummer i XXXXXXXXXXX-XXXXXXX-XXXXXXX-X "
+"format."
+
+#: contrib/localflavor/jp/jp_prefectures.py:4
+msgid "Hokkaido"
+msgstr "Hokkaido"
+
+#: contrib/localflavor/jp/jp_prefectures.py:5
+msgid "Aomori"
+msgstr "Aomori"
+
+#: contrib/localflavor/jp/jp_prefectures.py:6
+msgid "Iwate"
+msgstr "Iwate"
+
+#: contrib/localflavor/jp/jp_prefectures.py:7
+msgid "Miyagi"
+msgstr "Miyagi"
+
+#: contrib/localflavor/jp/jp_prefectures.py:8
+msgid "Akita"
+msgstr "Akita"
+
+#: contrib/localflavor/jp/jp_prefectures.py:9
+msgid "Yamagata"
+msgstr "Yamagata"
+
+#: contrib/localflavor/jp/jp_prefectures.py:10
+msgid "Fukushima"
+msgstr "Fukushima"
+
+#: contrib/localflavor/jp/jp_prefectures.py:11
+msgid "Ibaraki"
+msgstr "Ibaraki"
+
+#: contrib/localflavor/jp/jp_prefectures.py:12
+msgid "Tochigi"
+msgstr "Tochigi"
+
+#: contrib/localflavor/jp/jp_prefectures.py:13
+msgid "Gunma"
+msgstr "Gunma"
+
+#: contrib/localflavor/jp/jp_prefectures.py:14
+msgid "Saitama"
+msgstr "Saitama"
+
+#: contrib/localflavor/jp/jp_prefectures.py:15
+msgid "Chiba"
+msgstr "Chiba"
+
+#: contrib/localflavor/jp/jp_prefectures.py:16
+msgid "Tokyo"
+msgstr "Tokyo"
+
+#: contrib/localflavor/jp/jp_prefectures.py:17
+msgid "Kanagawa"
+msgstr "Kanagawa"
+
+#: contrib/localflavor/jp/jp_prefectures.py:18
+msgid "Yamanashi"
+msgstr "Yamanashi"
+
+#: contrib/localflavor/jp/jp_prefectures.py:19
+msgid "Nagano"
+msgstr "Nagano"
+
+#: contrib/localflavor/jp/jp_prefectures.py:20
+msgid "Niigata"
+msgstr "Niigata"
+
+#: contrib/localflavor/jp/jp_prefectures.py:21
+msgid "Toyama"
+msgstr "Toyama"
+
+#: contrib/localflavor/jp/jp_prefectures.py:22
+msgid "Ishikawa"
+msgstr "Ischikawa"
+
+#: contrib/localflavor/jp/jp_prefectures.py:23
+msgid "Fukui"
+msgstr "Fukui"
+
+#: contrib/localflavor/jp/jp_prefectures.py:24
+msgid "Gifu"
+msgstr "Gifu"
+
+#: contrib/localflavor/jp/jp_prefectures.py:25
+msgid "Shizuoka"
+msgstr "Shizuoka"
+
+#: contrib/localflavor/jp/jp_prefectures.py:26
+msgid "Aichi"
+msgstr "Aichi"
+
+#: contrib/localflavor/jp/jp_prefectures.py:27
+msgid "Mie"
+msgstr "Mie"
+
+#: contrib/localflavor/jp/jp_prefectures.py:28
+msgid "Shiga"
+msgstr "Shiga"
+
+#: contrib/localflavor/jp/jp_prefectures.py:29
+msgid "Kyoto"
+msgstr "Kyoto"
+
+#: contrib/localflavor/jp/jp_prefectures.py:30
+msgid "Osaka"
+msgstr "Osaka"
+
+#: contrib/localflavor/jp/jp_prefectures.py:31
+msgid "Hyogo"
+msgstr "Hyogo"
+
+#: contrib/localflavor/jp/jp_prefectures.py:32
+msgid "Nara"
+msgstr "Nara"
+
+#: contrib/localflavor/jp/jp_prefectures.py:33
+msgid "Wakayama"
+msgstr "Wakayama"
+
+#: contrib/localflavor/jp/jp_prefectures.py:34
+msgid "Tottori"
+msgstr "Tottori"
+
+#: contrib/localflavor/jp/jp_prefectures.py:35
+msgid "Shimane"
+msgstr "Shimane"
+
+#: contrib/localflavor/jp/jp_prefectures.py:36
+msgid "Okayama"
+msgstr "Okayama"
+
+#: contrib/localflavor/jp/jp_prefectures.py:37
+msgid "Hiroshima"
+msgstr "Hiroshima"
+
+#: contrib/localflavor/jp/jp_prefectures.py:38
+msgid "Yamaguchi"
+msgstr "Yamaguchi"
+
+#: contrib/localflavor/jp/jp_prefectures.py:39
+msgid "Tokushima"
+msgstr "Tokushima"
+
+#: contrib/localflavor/jp/jp_prefectures.py:40
+msgid "Kagawa"
+msgstr "Kagawa"
+
+#: contrib/localflavor/jp/jp_prefectures.py:41
+msgid "Ehime"
+msgstr "Ehime"
+
+#: contrib/localflavor/jp/jp_prefectures.py:42
+msgid "Kochi"
+msgstr "Kochi"
+
+#: contrib/localflavor/jp/jp_prefectures.py:43
+msgid "Fukuoka"
+msgstr "Fukuoka"
+
+#: contrib/localflavor/jp/jp_prefectures.py:44
+msgid "Saga"
+msgstr "Saga"
+
+#: contrib/localflavor/jp/jp_prefectures.py:45
+msgid "Nagasaki"
+msgstr "Nagasaki"
+
+#: contrib/localflavor/jp/jp_prefectures.py:46
+msgid "Kumamoto"
+msgstr "Kuamoto"
+
+#: contrib/localflavor/jp/jp_prefectures.py:47
+msgid "Oita"
+msgstr "Oita"
+
+#: contrib/localflavor/jp/jp_prefectures.py:48
+msgid "Miyazaki"
+msgstr "Miyazaki"
+
+#: contrib/localflavor/jp/jp_prefectures.py:49
+msgid "Kagoshima"
+msgstr "kagoshima"
+
+#: contrib/localflavor/jp/jp_prefectures.py:50
+msgid "Okinawa"
+msgstr "Okinawa"
+
+#: contrib/localflavor/jp/forms.py:21
+msgid "Enter a postal code in the format XXXXXXX or XXX-XXXX."
+msgstr "Fyll i zipkod i formatet XXXXXXX eller XXX-XXXX."
+
+#: contrib/localflavor/it/forms.py:16
+msgid "Enter a valid zip code."
+msgstr "Fyll i en giltigt zipkod."
+
+#: contrib/localflavor/it/forms.py:41
+msgid "Enter a valid Social Security number."
+msgstr "Fyll i ett giltigt personnummer."
+
+#: contrib/localflavor/it/forms.py:68
+msgid "Enter a valid VAT number."
+msgstr "Fyll i ett giltigt VAT-nummer."
+
+#: contrib/localflavor/no/forms.py:15 contrib/localflavor/ch/forms.py:18
+msgid "Enter a zip code in the format XXXX."
+msgstr "Fyll i zipkod i formatet XXXX."
+
+#: contrib/localflavor/no/forms.py:36
+msgid "Enter a valid Norwegian social security number."
+msgstr "Fyll i ett giltigt norskt personnummer."
+
+#: contrib/localflavor/fi/forms.py:40 contrib/localflavor/fi/forms.py:45
+msgid "Enter a valid Finnish social security number."
+msgstr "Fyll i ett giltigt finskt personnummer."
+
+#: contrib/localflavor/us/forms.py:18
msgid "Enter a zip code in the format XXXXX or XXXXX-XXXX."
msgstr "Fyll i zipkod i formatet XXXXX eller XXXXX-XXXX."
+#: contrib/localflavor/us/forms.py:51
+msgid "Enter a valid U.S. Social Security number in XXX-XX-XXXX format."
+msgstr "Fyll i ett giltigt amerikanskt personnummer i XXX-XX-XXXX format."
+
+#: contrib/localflavor/is_/forms.py:16
+msgid ""
+"Enter a valid Icelandic identification number. The format is XXXXXX-XXXX."
+msgstr "Fyll i ett giltigt isländskt personnummer. Formatet är XXXXXX-XXXX."
+
+#: contrib/localflavor/is_/forms.py:30
+msgid "The Icelandic identification number is not valid."
+msgstr "Det isländska personnumret är inte giltigt."
+
+#: contrib/localflavor/cl/forms.py:21
+msgid "Enter valid a Chilean RUT. The format is XX.XXX.XXX-X."
+msgstr "Fyll i ett giltigt chileanskt RUT. Formatet är XX.XXX.XXX-X."
+
+#: contrib/localflavor/cl/forms.py:26
+msgid "Enter valid a Chilean RUT"
+msgstr "Fyll i ett giltigt chileanskt RUT"
+
+#: contrib/localflavor/ch/ch_states.py:5
+msgid "Aargau"
+msgstr "Aargau"
+
+#: contrib/localflavor/ch/ch_states.py:6
+msgid "Appenzell Innerrhoden"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:7
+msgid "Appenzell Ausserrhoden"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:8
+msgid "Basel-Stadt"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:9
+msgid "Basel-Land"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:10
+msgid "Berne"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:11
+msgid "Fribourg"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:12
+msgid "Geneva"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:13
+msgid "Glarus"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:14
+msgid "Graubuenden"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:15
+msgid "Jura"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:16
+msgid "Lucerne"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:17
+msgid "Neuchatel"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:18
+msgid "Nidwalden"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:19
+msgid "Obwalden"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:20
+msgid "Schaffhausen"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:21
+msgid "Schwyz"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:22
+msgid "Solothurn"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:23
+msgid "St. Gallen"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:24
+msgid "Thurgau"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:25
+msgid "Ticino"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:26
+msgid "Uri"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:27
+msgid "Valais"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:28
+msgid "Vaud"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:29
+msgid "Zug"
+msgstr ""
+
+#: contrib/localflavor/ch/ch_states.py:30
+msgid "Zurich"
+msgstr ""
+
+#: contrib/localflavor/ch/forms.py:90
+msgid ""
+"Enter a valid Swiss identity or passport card number in X1234567<0 or "
+"1234567890 format."
+msgstr ""
+"Fyll i ett giltigt Schweiziskt ID- eller passkortnummer i X1234567<0 eller "
+"1234567890 format."
+
+#: contrib/sessions/models.py:68
+msgid "session key"
+msgstr "sessionsnyckel"
+
+#: contrib/sessions/models.py:69
+msgid "session data"
+msgstr "sessionsdata"
+
+#: contrib/sessions/models.py:70
+msgid "expire date"
+msgstr "utgångsdatum"
+
+#: contrib/sessions/models.py:74
+msgid "session"
+msgstr "session"
+
+#: contrib/sessions/models.py:75
+msgid "sessions"
+msgstr "sessioner"
+
+#: contrib/flatpages/models.py:8
+msgid ""
+"Example: '/about/contact/'. Make sure to have leading and trailing slashes."
+msgstr ""
+"Exempel: '/om/kontakt/'. Se till att ha inledande och avslutande snedsträck."
+
+#: contrib/flatpages/models.py:9
+msgid "title"
+msgstr "titel"
+
+#: contrib/flatpages/models.py:10
+msgid "content"
+msgstr "innehåll"
+
+#: contrib/flatpages/models.py:11
+msgid "enable comments"
+msgstr "aktivera kommentarer"
+
+#: contrib/flatpages/models.py:12
+msgid "template name"
+msgstr "mallnamn"
+
+#: contrib/flatpages/models.py:13
+msgid ""
+"Example: 'flatpages/contact_page.html'. If this isn't provided, the system "
+"will use 'flatpages/default.html'."
+msgstr ""
+"Exempel: 'sidor/kontaktsida.html'. Om det här inte fylls i kommer systemet "
+"att använda 'sidor/default.html'."
+
+#: contrib/flatpages/models.py:14
+msgid "registration required"
+msgstr "registrering krävs"
+
+#: contrib/flatpages/models.py:14
+msgid "If this is checked, only logged-in users will be able to view the page."
+msgstr ""
+"Om det här bockas i kommer endast inloggade användare att kunna visa sidan"
+
+#: contrib/flatpages/models.py:18
+msgid "flat page"
+msgstr "flatsida"
+
+#: contrib/flatpages/models.py:19
+msgid "flat pages"
+msgstr "flatsidor"
+
#: utils/dates.py:6
msgid "Monday"
msgstr "Måndag"
@@ -2204,7 +2826,7 @@ msgstr "November"
#: utils/dates.py:16
msgid "December"
-msgstr "december"
+msgstr "December"
#: utils/dates.py:19
msgid "jan"
@@ -2318,27 +2940,87 @@ msgid_plural "minutes"
msgstr[0] "minut"
msgstr[1] "minuter"
-#: utils/translation/trans_real.py:362
+#: utils/timesince.py:40
+#, python-format
+msgid "%d milliseconds"
+msgstr "%d millisekunder"
+
+#: utils/timesince.py:41
+#, python-format
+msgid "%(number)d %(type)s"
+msgstr "%(number)d %(type)s"
+
+#: utils/timesince.py:47
+#, python-format
+msgid ", %(number)d %(type)s"
+msgstr ", %(number)d %(type)s"
+
+#: utils/dateformat.py:40
+msgid "p.m."
+msgstr "p.m."
+
+#: utils/dateformat.py:41
+msgid "a.m."
+msgstr "a.m."
+
+#: utils/dateformat.py:46
+msgid "PM"
+msgstr "PM"
+
+#: utils/dateformat.py:47
+msgid "AM"
+msgstr "AM"
+
+#: utils/dateformat.py:95
+msgid "midnight"
+msgstr "midnatt"
+
+#: utils/dateformat.py:97
+msgid "noon"
+msgstr "middag"
+
+#: utils/translation/trans_real.py:358
msgid "DATE_FORMAT"
-msgstr ""
+msgstr "N j, Y"
-#: utils/translation/trans_real.py:363
+#: utils/translation/trans_real.py:359
msgid "DATETIME_FORMAT"
-msgstr ""
+msgstr "N j, Y, P"
-#: utils/translation/trans_real.py:364
+#: utils/translation/trans_real.py:360
msgid "TIME_FORMAT"
-msgstr ""
+msgstr "P"
-#: utils/translation/trans_real.py:380
+#: utils/translation/trans_real.py:376
msgid "YEAR_MONTH_FORMAT"
-msgstr ""
+msgstr "F Y"
-#: utils/translation/trans_real.py:381
+#: utils/translation/trans_real.py:377
msgid "MONTH_DAY_FORMAT"
-msgstr ""
+msgstr "F j"
-#: template/defaultfilters.py:490
+#: template/defaultfilters.py:491
msgid "yes,no,maybe"
msgstr "ja,nej,kanske"
+#: template/defaultfilters.py:520
+#, python-format
+msgid "%(size)d byte"
+msgid_plural "%(size)d bytes"
+msgstr[0] "%(size)d byte"
+msgstr[1] "%(size)d bytes"
+
+#: template/defaultfilters.py:522
+#, python-format
+msgid "%.1f KB"
+msgstr "%.1f KB"
+
+#: template/defaultfilters.py:524
+#, python-format
+msgid "%.1f MB"
+msgstr "%.1f MB"
+
+#: template/defaultfilters.py:525
+#, python-format
+msgid "%.1f GB"
+msgstr "%.1f GB"
diff --git a/django/conf/locale/sv/LC_MESSAGES/djangojs.po b/django/conf/locale/sv/LC_MESSAGES/djangojs.po
index 5abc8780d5..29fbe2eb15 100644
--- a/django/conf/locale/sv/LC_MESSAGES/djangojs.po
+++ b/django/conf/locale/sv/LC_MESSAGES/djangojs.po
@@ -2,9 +2,6 @@
# Copyright (C) 2005
# This file is distributed under the same license as the Django package.
#
-#
-# Robin Sonefors <ozamosi@blinkenlights.se>, 2005.
-# Mikko Hellsing <mikko@sorl.net>, 2007.
msgid ""
msgstr ""
"Project-Id-Version: djangojs\n"
diff --git a/django/contrib/admin/templatetags/admin_modify.py b/django/contrib/admin/templatetags/admin_modify.py
index f9cad005d5..b8836caa5a 100644
--- a/django/contrib/admin/templatetags/admin_modify.py
+++ b/django/contrib/admin/templatetags/admin_modify.py
@@ -94,15 +94,15 @@ class FieldWidgetNode(template.Node):
return cls.nodelists[klass]
get_nodelist = classmethod(get_nodelist)
- def render(self, context):
+ def iter_render(self, context):
bound_field = template.resolve_variable(self.bound_field_var, context)
context.push()
context['bound_field'] = bound_field
- output = self.get_nodelist(bound_field.field.__class__).render(context)
+ for chunk in self.get_nodelist(bound_field.field.__class__).iter_render(context):
+ yield chunk
context.pop()
- return output
class FieldWrapper(object):
def __init__(self, field ):
@@ -157,7 +157,7 @@ class EditInlineNode(template.Node):
def __init__(self, rel_var):
self.rel_var = rel_var
- def render(self, context):
+ def iter_render(self, context):
relation = template.resolve_variable(self.rel_var, context)
context.push()
if relation.field.rel.edit_inline == models.TABULAR:
@@ -169,10 +169,9 @@ class EditInlineNode(template.Node):
original = context.get('original', None)
bound_related_object = relation.bind(context['form'], original, bound_related_object_class)
context['bound_related_object'] = bound_related_object
- t = loader.get_template(bound_related_object.template_name())
- output = t.render(context)
+ for chunk in loader.get_template(bound_related_object.template_name()).iter_render(context):
+ yield chunk
context.pop()
- return output
def output_all(form_fields):
return ''.join([str(f) for f in form_fields])
diff --git a/django/contrib/admin/templatetags/adminapplist.py b/django/contrib/admin/templatetags/adminapplist.py
index 10e09ca0b6..53455d6c74 100644
--- a/django/contrib/admin/templatetags/adminapplist.py
+++ b/django/contrib/admin/templatetags/adminapplist.py
@@ -7,7 +7,7 @@ class AdminApplistNode(template.Node):
def __init__(self, varname):
self.varname = varname
- def render(self, context):
+ def iter_render(self, context):
from django.db import models
from django.utils.text import capfirst
app_list = []
@@ -54,7 +54,7 @@ class AdminApplistNode(template.Node):
'models': model_list,
})
context[self.varname] = app_list
- return ''
+ return ()
def get_admin_app_list(parser, token):
"""
diff --git a/django/contrib/admin/templatetags/log.py b/django/contrib/admin/templatetags/log.py
index 8d52d2e944..96db2373b4 100644
--- a/django/contrib/admin/templatetags/log.py
+++ b/django/contrib/admin/templatetags/log.py
@@ -10,14 +10,14 @@ class AdminLogNode(template.Node):
def __repr__(self):
return "<GetAdminLog Node>"
- def render(self, context):
+ def iter_render(self, context):
if self.user is None:
context[self.varname] = LogEntry.objects.all().select_related()[:self.limit]
else:
if not self.user.isdigit():
self.user = context[self.user].id
context[self.varname] = LogEntry.objects.filter(user__id__exact=self.user).select_related()[:self.limit]
- return ''
+ return ()
class DoGetAdminLog:
"""
diff --git a/django/contrib/auth/__init__.py b/django/contrib/auth/__init__.py
index d37450805f..14ae020674 100644
--- a/django/contrib/auth/__init__.py
+++ b/django/contrib/auth/__init__.py
@@ -53,6 +53,8 @@ def login(request, user):
user.save()
request.session[SESSION_KEY] = user.id
request.session[BACKEND_SESSION_KEY] = user.backend
+ if hasattr(request, 'user'):
+ request.user = user
def logout(request):
"""
@@ -66,6 +68,9 @@ def logout(request):
del request.session[BACKEND_SESSION_KEY]
except KeyError:
pass
+ if hasattr(request, 'user'):
+ from django.contrib.auth.models import AnonymousUser
+ request.user = AnonymousUser()
def get_user(request):
from django.contrib.auth.models import AnonymousUser
diff --git a/django/contrib/comments/templatetags/comments.py b/django/contrib/comments/templatetags/comments.py
index 5c02c16f95..a43b11f452 100644
--- a/django/contrib/comments/templatetags/comments.py
+++ b/django/contrib/comments/templatetags/comments.py
@@ -24,7 +24,7 @@ class CommentFormNode(template.Node):
self.photo_options, self.rating_options = photo_options, rating_options
self.is_public = is_public
- def render(self, context):
+ def iter_render(self, context):
from django.conf import settings
from django.utils.text import normalize_newlines
import base64
@@ -33,7 +33,7 @@ class CommentFormNode(template.Node):
try:
self.obj_id = template.resolve_variable(self.obj_id_lookup_var, context)
except template.VariableDoesNotExist:
- return ''
+ return
# Validate that this object ID is valid for this content-type.
# We only have to do this validation if obj_id_lookup_var is provided,
# because do_comment_form() validates hard-coded object IDs.
@@ -67,9 +67,9 @@ class CommentFormNode(template.Node):
context['hash'] = Comment.objects.get_security_hash(context['options'], context['photo_options'], context['rating_options'], context['target'])
context['logout_url'] = settings.LOGOUT_URL
default_form = loader.get_template(COMMENT_FORM)
- output = default_form.render(context)
+ for chunk in default_form.iter_render(context):
+ yield chunk
context.pop()
- return output
class CommentCountNode(template.Node):
def __init__(self, package, module, context_var_name, obj_id, var_name, free):
@@ -77,7 +77,7 @@ class CommentCountNode(template.Node):
self.context_var_name, self.obj_id = context_var_name, obj_id
self.var_name, self.free = var_name, free
- def render(self, context):
+ def iter_render(self, context):
from django.conf import settings
manager = self.free and FreeComment.objects or Comment.objects
if self.context_var_name is not None:
@@ -86,7 +86,7 @@ class CommentCountNode(template.Node):
content_type__app_label__exact=self.package,
content_type__model__exact=self.module, site__id__exact=settings.SITE_ID).count()
context[self.var_name] = comment_count
- return ''
+ return ()
class CommentListNode(template.Node):
def __init__(self, package, module, context_var_name, obj_id, var_name, free, ordering, extra_kwargs=None):
@@ -96,14 +96,14 @@ class CommentListNode(template.Node):
self.ordering = ordering
self.extra_kwargs = extra_kwargs or {}
- def render(self, context):
+ def iter_render(self, context):
from django.conf import settings
get_list_function = self.free and FreeComment.objects.filter or Comment.objects.get_list_with_karma
if self.context_var_name is not None:
try:
self.obj_id = template.resolve_variable(self.context_var_name, context)
except template.VariableDoesNotExist:
- return ''
+ return ()
kwargs = {
'object_id__exact': self.obj_id,
'content_type__app_label__exact': self.package,
@@ -127,7 +127,7 @@ class CommentListNode(template.Node):
comment_list = [c for c in comment_list if not c.is_hidden or (user_id == c.user_id)]
context[self.var_name] = comment_list
- return ''
+ return ()
class DoCommentForm:
"""
diff --git a/django/contrib/sessions/models.py b/django/contrib/sessions/models.py
index 77718407e1..521a2abee9 100644
--- a/django/contrib/sessions/models.py
+++ b/django/contrib/sessions/models.py
@@ -1,4 +1,4 @@
-import base64, md5, random, sys, datetime
+import base64, md5, random, sys, datetime, os, time
import cPickle as pickle
from django.db import models
from django.utils.translation import gettext_lazy as _
@@ -14,9 +14,9 @@ class SessionManager(models.Manager):
def get_new_session_key(self):
"Returns session key that isn't being used."
# The random module is seeded when this Apache child is created.
- # Use person_id and SECRET_KEY as added salt.
+ # Use SECRET_KEY as added salt.
while 1:
- session_key = md5.new(str(random.randint(0, sys.maxint - 1)) + str(random.randint(0, sys.maxint - 1)) + settings.SECRET_KEY).hexdigest()
+ session_key = md5.new("%s%s%s%s" % (random.randint(0, sys.maxint - 1), os.getpid(), time.time(), settings.SECRET_KEY)).hexdigest()
try:
self.get(session_key=session_key)
except self.model.DoesNotExist:
diff --git a/django/core/servers/basehttp.py b/django/core/servers/basehttp.py
index 80a0bf6a91..9e603b42d4 100644
--- a/django/core/servers/basehttp.py
+++ b/django/core/servers/basehttp.py
@@ -309,7 +309,7 @@ class ServerHandler(object):
"""
if not self.result_is_file() and not self.sendfile():
for data in self.result:
- self.write(data)
+ self.write(data, False)
self.finish_content()
self.close()
@@ -377,7 +377,7 @@ class ServerHandler(object):
else:
self._write('Status: %s\r\n' % self.status)
- def write(self, data):
+ def write(self, data, flush=True):
"""'write()' callable as specified by PEP 333"""
assert type(data) is StringType,"write() argument must be string"
@@ -394,7 +394,8 @@ class ServerHandler(object):
# XXX check Content-Length and truncate if too many bytes written?
self._write(data)
- self._flush()
+ if flush:
+ self._flush()
def sendfile(self):
"""Platform-specific file transmission
@@ -421,8 +422,6 @@ class ServerHandler(object):
if not self.headers_sent:
self.headers['Content-Length'] = "0"
self.send_headers()
- else:
- pass # XXX check if content-length was too short?
def close(self):
try:
diff --git a/django/http/__init__.py b/django/http/__init__.py
index ca3b5eab24..a8c8afe433 100644
--- a/django/http/__init__.py
+++ b/django/http/__init__.py
@@ -222,6 +222,12 @@ class HttpResponse(object):
content = ''.join(self._container)
if isinstance(content, unicode):
content = content.encode(self._charset)
+
+ # If self._container was an iterator, we have just exhausted it, so we
+ # need to save the results for anything else that needs access
+ if not self._is_string:
+ self._container = [content]
+ self._is_string = True
return content
def _set_content(self, value):
@@ -231,14 +237,10 @@ class HttpResponse(object):
content = property(_get_content, _set_content)
def __iter__(self):
- self._iterator = self._container.__iter__()
- return self
-
- def next(self):
- chunk = self._iterator.next()
- if isinstance(chunk, unicode):
- chunk = chunk.encode(self._charset)
- return chunk
+ for chunk in self._container:
+ if isinstance(chunk, unicode):
+ chunk = chunk.encode(self._charset)
+ yield chunk
def close(self):
if hasattr(self._container, 'close'):
diff --git a/django/middleware/common.py b/django/middleware/common.py
index 5f671dff7d..9610e1e952 100644
--- a/django/middleware/common.py
+++ b/django/middleware/common.py
@@ -11,7 +11,8 @@ class CommonMiddleware(object):
- Forbids access to User-Agents in settings.DISALLOWED_USER_AGENTS
- URL rewriting: Based on the APPEND_SLASH and PREPEND_WWW settings,
- this middleware appends missing slashes and/or prepends missing "www."s.
+ this middleware appends missing slashes and/or prepends missing
+ "www."s.
- ETags: If the USE_ETAGS setting is set, ETags will be calculated from
the entire page content and Not Modified responses will be returned
@@ -74,7 +75,10 @@ class CommonMiddleware(object):
# Use ETags, if requested.
if settings.USE_ETAGS:
- etag = md5.new(response.content).hexdigest()
+ if response.has_header('ETag'):
+ etag = response['ETag']
+ else:
+ etag = md5.new(response.content).hexdigest()
if response.status_code >= 200 and response.status_code < 300 and request.META.get('HTTP_IF_NONE_MATCH') == etag:
response = http.HttpResponseNotModified()
else:
diff --git a/django/newforms/models.py b/django/newforms/models.py
index 1f783429be..d51b06c78c 100644
--- a/django/newforms/models.py
+++ b/django/newforms/models.py
@@ -19,9 +19,8 @@ def save_instance(form, instance, fields=None, fail_message='saved', commit=True
"""
Saves bound Form ``form``'s cleaned_data into model instance ``instance``.
- Assumes ``form`` has a field for every non-AutoField database field in
- ``instance``. If commit=True, then the changes to ``instance`` will be
- saved to the database. Returns ``instance``.
+ If commit=True, then the changes to ``instance`` will be saved to the
+ database. Returns ``instance``.
"""
from django.db import models
opts = instance.__class__._meta
diff --git a/django/oldforms/__init__.py b/django/oldforms/__init__.py
index 5814eef7ff..ea1f425ad3 100644
--- a/django/oldforms/__init__.py
+++ b/django/oldforms/__init__.py
@@ -309,6 +309,10 @@ class FormField(object):
return data
html2python = staticmethod(html2python)
+ def iter_render(self, data):
+ # this even needed?
+ return (self.render(data),)
+
def render(self, data):
raise NotImplementedError
diff --git a/django/shortcuts/__init__.py b/django/shortcuts/__init__.py
index 81381d08c1..3a0f6a0091 100644
--- a/django/shortcuts/__init__.py
+++ b/django/shortcuts/__init__.py
@@ -7,7 +7,7 @@ from django.http import HttpResponse, Http404
from django.db.models.manager import Manager
def render_to_response(*args, **kwargs):
- return HttpResponse(loader.render_to_string(*args, **kwargs))
+ return HttpResponse(loader.render_to_iter(*args, **kwargs))
load_and_render = render_to_response # For backwards compatibility.
def get_object_or_404(klass, *args, **kwargs):
diff --git a/django/template/__init__.py b/django/template/__init__.py
index 4f2ddfc8b3..7495eea878 100644
--- a/django/template/__init__.py
+++ b/django/template/__init__.py
@@ -55,6 +55,7 @@ times with multiple contexts)
'\n<html>\n\n</html>\n'
"""
import re
+import types
from inspect import getargspec
from django.conf import settings
from django.template.context import Context, RequestContext, ContextPopException
@@ -167,9 +168,12 @@ class Template(object):
for subnode in node:
yield subnode
- def render(self, context):
+ def iter_render(self, context):
"Display stage -- can be called many times"
- return self.nodelist.render(context)
+ return self.nodelist.iter_render(context)
+
+ def render(self, context):
+ return ''.join(self.iter_render(context))
def compile_string(template_string, origin):
"Compiles template_string into NodeList ready for rendering"
@@ -488,9 +492,6 @@ class TokenParser(object):
self.pointer = i
return s
-
-
-
filter_raw_string = r"""
^%(i18n_open)s"(?P<i18n_constant>%(str)s)"%(i18n_close)s|
^"(?P<constant>%(str)s)"|
@@ -698,10 +699,26 @@ def resolve_variable(path, context):
del bits[0]
return current
+class NodeBase(type):
+ def __new__(cls, name, bases, attrs):
+ """
+ Ensures that either a 'render' or 'render_iter' method is defined on
+ any Node sub-class. This avoids potential infinite loops at runtime.
+ """
+ if not (isinstance(attrs.get('render'), types.FunctionType) or
+ isinstance(attrs.get('iter_render'), types.FunctionType)):
+ raise TypeError('Unable to create Node subclass without either "render" or "iter_render" method.')
+ return type.__new__(cls, name, bases, attrs)
+
class Node(object):
+ __metaclass__ = NodeBase
+
+ def iter_render(self, context):
+ return (self.render(context),)
+
def render(self, context):
"Return the node rendered as a string"
- pass
+ return ''.join(self.iter_render(context))
def __iter__(self):
yield self
@@ -717,13 +734,12 @@ class Node(object):
class NodeList(list):
def render(self, context):
- bits = []
+ return ''.join(self.iter_render(context))
+
+ def iter_render(self, context):
for node in self:
- if isinstance(node, Node):
- bits.append(self.render_node(node, context))
- else:
- bits.append(node)
- return ''.join(bits)
+ for chunk in node.iter_render(context):
+ yield chunk
def get_nodes_by_type(self, nodetype):
"Return a list of all nodes of the given type"
@@ -732,24 +748,25 @@ class NodeList(list):
nodes.extend(node.get_nodes_by_type(nodetype))
return nodes
- def render_node(self, node, context):
- return(node.render(context))
-
class DebugNodeList(NodeList):
- def render_node(self, node, context):
- try:
- result = node.render(context)
- except TemplateSyntaxError, e:
- if not hasattr(e, 'source'):
- e.source = node.source
- raise
- except Exception, e:
- from sys import exc_info
- wrapped = TemplateSyntaxError('Caught an exception while rendering: %s' % e)
- wrapped.source = node.source
- wrapped.exc_info = exc_info()
- raise wrapped
- return result
+ def iter_render(self, context):
+ for node in self:
+ if not isinstance(node, Node):
+ yield node
+ continue
+ try:
+ for chunk in node.iter_render(context):
+ yield chunk
+ except TemplateSyntaxError, e:
+ if not hasattr(e, 'source'):
+ e.source = node.source
+ raise
+ except Exception, e:
+ from sys import exc_info
+ wrapped = TemplateSyntaxError('Caught an exception while rendering: %s' % e)
+ wrapped.source = node.source
+ wrapped.exc_info = exc_info()
+ raise wrapped
class TextNode(Node):
def __init__(self, s):
@@ -758,6 +775,9 @@ class TextNode(Node):
def __repr__(self):
return "<Text Node: '%s'>" % self.s[:25]
+ def iter_render(self, context):
+ return (self.s,)
+
def render(self, context):
return self.s
@@ -781,6 +801,9 @@ class VariableNode(Node):
else:
return output
+ def iter_render(self, context):
+ return (self.render(context),)
+
def render(self, context):
output = self.filter_expression.resolve(context)
return self.encode_output(output)
@@ -869,6 +892,9 @@ class Library(object):
def __init__(self, vars_to_resolve):
self.vars_to_resolve = vars_to_resolve
+ #def iter_render(self, context):
+ # return (self.render(context),)
+
def render(self, context):
resolved_vars = [resolve_variable(var, context) for var in self.vars_to_resolve]
return func(*resolved_vars)
@@ -891,7 +917,7 @@ class Library(object):
def __init__(self, vars_to_resolve):
self.vars_to_resolve = vars_to_resolve
- def render(self, context):
+ def iter_render(self, context):
resolved_vars = [resolve_variable(var, context) for var in self.vars_to_resolve]
if takes_context:
args = [context] + resolved_vars
@@ -907,7 +933,7 @@ class Library(object):
else:
t = get_template(file_name)
self.nodelist = t.nodelist
- return self.nodelist.render(context_class(dict))
+ return self.nodelist.iter_render(context_class(dict))
compile_func = curry(generic_tag_compiler, params, defaults, getattr(func, "_decorated_function", func).__name__, InclusionNode)
compile_func.__doc__ = func.__doc__
diff --git a/django/template/defaulttags.py b/django/template/defaulttags.py
index 6a6665a445..77fac6bec5 100644
--- a/django/template/defaulttags.py
+++ b/django/template/defaulttags.py
@@ -4,6 +4,7 @@ from django.template import Node, NodeList, Template, Context, resolve_variable
from django.template import TemplateSyntaxError, VariableDoesNotExist, BLOCK_TAG_START, BLOCK_TAG_END, VARIABLE_TAG_START, VARIABLE_TAG_END, SINGLE_BRACE_START, SINGLE_BRACE_END, COMMENT_TAG_START, COMMENT_TAG_END
from django.template import get_library, Library, InvalidTemplateLibrary
from django.conf import settings
+from django.utils.itercompat import groupby
import sys
import re
@@ -14,12 +15,11 @@ if not hasattr(__builtins__, 'reversed'):
for index in xrange(len(data)-1, -1, -1):
yield data[index]
-
register = Library()
class CommentNode(Node):
- def render(self, context):
- return ''
+ def iter_render(self, context):
+ return ()
class CycleNode(Node):
def __init__(self, cyclevars, variable_name=None):
@@ -28,6 +28,9 @@ class CycleNode(Node):
self.counter = -1
self.variable_name = variable_name
+ def iter_render(self, context):
+ return (self.render(context),)
+
def render(self, context):
self.counter += 1
value = self.cyclevars[self.counter % self.cyclevars_len]
@@ -36,29 +39,32 @@ class CycleNode(Node):
return value
class DebugNode(Node):
- def render(self, context):
+ def iter_render(self, context):
from pprint import pformat
- output = [pformat(val) for val in context]
- output.append('\n\n')
- output.append(pformat(sys.modules))
- return ''.join(output)
+ for val in context:
+ yield pformat(val)
+ yield "\n\n"
+ yield pformat(sys.modules)
class FilterNode(Node):
def __init__(self, filter_expr, nodelist):
self.filter_expr, self.nodelist = filter_expr, nodelist
- def render(self, context):
+ def iter_render(self, context):
output = self.nodelist.render(context)
# apply filters
context.update({'var': output})
filtered = self.filter_expr.resolve(context)
context.pop()
- return filtered
+ return (filtered,)
class FirstOfNode(Node):
def __init__(self, vars):
self.vars = vars
+ def iter_render(self, context):
+ return (self.render(context),)
+
def render(self, context):
for var in self.vars:
try:
@@ -94,8 +100,7 @@ class ForNode(Node):
nodes.extend(self.nodelist_loop.get_nodes_by_type(nodetype))
return nodes
- def render(self, context):
- nodelist = NodeList()
+ def iter_render(self, context):
if 'forloop' in context:
parentloop = context['forloop']
else:
@@ -103,12 +108,12 @@ class ForNode(Node):
context.push()
try:
values = self.sequence.resolve(context, True)
+ if values is None:
+ values = ()
+ elif not hasattr(values, '__len__'):
+ values = list(values)
except VariableDoesNotExist:
- values = []
- if values is None:
- values = []
- if not hasattr(values, '__len__'):
- values = list(values)
+ values = ()
len_values = len(values)
if self.reversed:
values = reversed(values)
@@ -127,12 +132,17 @@ class ForNode(Node):
'parentloop': parentloop,
}
if unpack:
- # If there are multiple loop variables, unpack the item into them.
+ # If there are multiple loop variables, unpack the item into
+ # them.
context.update(dict(zip(self.loopvars, item)))
else:
context[self.loopvars[0]] = item
+
+ # We inline this to avoid the overhead since ForNode is pretty
+ # common.
for node in self.nodelist_loop:
- nodelist.append(node.render(context))
+ for chunk in node.iter_render(context):
+ yield chunk
if unpack:
# The loop variables were pushed on to the context so pop them
# off again. This is necessary because the tag lets the length
@@ -141,7 +151,6 @@ class ForNode(Node):
# context.
context.pop()
context.pop()
- return nodelist.render(context)
class IfChangedNode(Node):
def __init__(self, nodelist, *varlist):
@@ -149,7 +158,7 @@ class IfChangedNode(Node):
self._last_seen = None
self._varlist = varlist
- def render(self, context):
+ def iter_render(self, context):
if 'forloop' in context and context['forloop']['first']:
self._last_seen = None
try:
@@ -167,11 +176,9 @@ class IfChangedNode(Node):
self._last_seen = compare_to
context.push()
context['ifchanged'] = {'firstloop': firstloop}
- content = self.nodelist.render(context)
+ for chunk in self.nodelist.iter_render(context):
+ yield chunk
context.pop()
- return content
- else:
- return ''
class IfEqualNode(Node):
def __init__(self, var1, var2, nodelist_true, nodelist_false, negate):
@@ -182,7 +189,7 @@ class IfEqualNode(Node):
def __repr__(self):
return "<IfEqualNode>"
- def render(self, context):
+ def iter_render(self, context):
try:
val1 = resolve_variable(self.var1, context)
except VariableDoesNotExist:
@@ -192,8 +199,8 @@ class IfEqualNode(Node):
except VariableDoesNotExist:
val2 = None
if (self.negate and val1 != val2) or (not self.negate and val1 == val2):
- return self.nodelist_true.render(context)
- return self.nodelist_false.render(context)
+ return self.nodelist_true.iter_render(context)
+ return self.nodelist_false.iter_render(context)
class IfNode(Node):
def __init__(self, bool_exprs, nodelist_true, nodelist_false, link_type):
@@ -218,7 +225,7 @@ class IfNode(Node):
nodes.extend(self.nodelist_false.get_nodes_by_type(nodetype))
return nodes
- def render(self, context):
+ def iter_render(self, context):
if self.link_type == IfNode.LinkTypes.or_:
for ifnot, bool_expr in self.bool_exprs:
try:
@@ -226,8 +233,8 @@ class IfNode(Node):
except VariableDoesNotExist:
value = None
if (value and not ifnot) or (ifnot and not value):
- return self.nodelist_true.render(context)
- return self.nodelist_false.render(context)
+ return self.nodelist_true.iter_render(context)
+ return self.nodelist_false.iter_render(context)
else:
for ifnot, bool_expr in self.bool_exprs:
try:
@@ -235,8 +242,8 @@ class IfNode(Node):
except VariableDoesNotExist:
value = None
if not ((value and not ifnot) or (ifnot and not value)):
- return self.nodelist_false.render(context)
- return self.nodelist_true.render(context)
+ return self.nodelist_false.iter_render(context)
+ return self.nodelist_true.iter_render(context)
class LinkTypes:
and_ = 0,
@@ -247,21 +254,16 @@ class RegroupNode(Node):
self.target, self.expression = target, expression
self.var_name = var_name
- def render(self, context):
+ def iter_render(self, context):
obj_list = self.target.resolve(context, True)
if obj_list == None: # target_var wasn't found in context; fail silently
context[self.var_name] = []
- return ''
- output = [] # list of dictionaries in the format {'grouper': 'key', 'list': [list of contents]}
- for obj in obj_list:
- grouper = self.expression.resolve(obj, True)
- # TODO: Is this a sensible way to determine equality?
- if output and repr(output[-1]['grouper']) == repr(grouper):
- output[-1]['list'].append(obj)
- else:
- output.append({'grouper': grouper, 'list': [obj]})
- context[self.var_name] = output
- return ''
+ return ()
+ # List of dictionaries in the format
+ # {'grouper': 'key', 'list': [list of contents]}.
+ context[self.var_name] = [{'grouper':key, 'list':list(val)} for key, val in
+ groupby(obj_list, lambda v, f=self.expression.resolve: f(v, True))]
+ return ()
def include_is_allowed(filepath):
for root in settings.ALLOWED_INCLUDE_ROOTS:
@@ -273,10 +275,10 @@ class SsiNode(Node):
def __init__(self, filepath, parsed):
self.filepath, self.parsed = filepath, parsed
- def render(self, context):
+ def iter_render(self, context):
if not include_is_allowed(self.filepath):
if settings.DEBUG:
- return "[Didn't have permission to include file]"
+ return ("[Didn't have permission to include file]",)
else:
return '' # Fail silently for invalid includes.
try:
@@ -287,23 +289,25 @@ class SsiNode(Node):
output = ''
if self.parsed:
try:
- t = Template(output, name=self.filepath)
- return t.render(context)
+ return Template(output, name=self.filepath).iter_render(context)
except TemplateSyntaxError, e:
if settings.DEBUG:
return "[Included template had syntax error: %s]" % e
else:
return '' # Fail silently for invalid included templates.
- return output
+ return (output,)
class LoadNode(Node):
- def render(self, context):
- return ''
+ def iter_render(self, context):
+ return ()
class NowNode(Node):
def __init__(self, format_string):
self.format_string = format_string
+ def iter_render(self, context):
+ return (self.render(context),)
+
def render(self, context):
from datetime import datetime
from django.utils.dateformat import DateFormat
@@ -332,6 +336,9 @@ class TemplateTagNode(Node):
def __init__(self, tagtype):
self.tagtype = tagtype
+ def iter_render(self, context):
+ return (self.render(context),)
+
def render(self, context):
return self.mapping.get(self.tagtype, '')
@@ -341,18 +348,18 @@ class URLNode(Node):
self.args = args
self.kwargs = kwargs
- def render(self, context):
+ def iter_render(self, context):
from django.core.urlresolvers import reverse, NoReverseMatch
args = [arg.resolve(context) for arg in self.args]
kwargs = dict([(k, v.resolve(context)) for k, v in self.kwargs.items()])
try:
- return reverse(self.view_name, args=args, kwargs=kwargs)
+ return (reverse(self.view_name, args=args, kwargs=kwargs),)
except NoReverseMatch:
try:
project_name = settings.SETTINGS_MODULE.split('.')[0]
return reverse(project_name + '.' + self.view_name, args=args, kwargs=kwargs)
except NoReverseMatch:
- return ''
+ return ()
class WidthRatioNode(Node):
def __init__(self, val_expr, max_expr, max_width):
@@ -360,6 +367,9 @@ class WidthRatioNode(Node):
self.max_expr = max_expr
self.max_width = max_width
+ def iter_render(self, context):
+ return (self.render(context),)
+
def render(self, context):
try:
value = self.val_expr.resolve(context)
@@ -383,13 +393,13 @@ class WithNode(Node):
def __repr__(self):
return "<WithNode>"
- def render(self, context):
+ def iter_render(self, context):
val = self.var.resolve(context)
context.push()
context[self.name] = val
- output = self.nodelist.render(context)
+ for chunk in self.nodelist.iter_render(context):
+ yield chunk
context.pop()
- return output
#@register.tag
def comment(parser, token):
diff --git a/django/template/loader.py b/django/template/loader.py
index 03e6f8d49d..45cf5a9d7c 100644
--- a/django/template/loader.py
+++ b/django/template/loader.py
@@ -87,14 +87,12 @@ def get_template_from_string(source, origin=None, name=None):
"""
return Template(source, origin, name)
-def render_to_string(template_name, dictionary=None, context_instance=None):
+def _render_setup(template_name, dictionary=None, context_instance=None):
"""
- Loads the given template_name and renders it with the given dictionary as
- context. The template_name may be a string to load a single template using
- get_template, or it may be a tuple to use select_template to find one of
- the templates in the list. Returns a string.
+ Common setup code for render_to_string and render_to_iter.
"""
- dictionary = dictionary or {}
+ if dictionary is None:
+ dictionary = {}
if isinstance(template_name, (list, tuple)):
t = select_template(template_name)
else:
@@ -103,7 +101,28 @@ def render_to_string(template_name, dictionary=None, context_instance=None):
context_instance.update(dictionary)
else:
context_instance = Context(dictionary)
- return t.render(context_instance)
+ return t, context_instance
+
+def render_to_string(template_name, dictionary=None, context_instance=None):
+ """
+ Loads the given template_name and renders it with the given dictionary as
+ context. The template_name may be a string to load a single template using
+ get_template, or it may be a tuple to use select_template to find one of
+ the templates in the list. Returns a string.
+ """
+ t, c = _render_setup(template_name, dictionary=dictionary, context_instance=context_instance)
+ return t.render(c)
+
+def render_to_iter(template_name, dictionary=None, context_instance=None):
+ """
+ Loads the given template_name and renders it with the given dictionary as
+ context. The template_name may be a string to load a single template using
+ get_template, or it may be a tuple to use select_template to find one of
+ the templates in the list. Returns a string.
+ """
+ t, c = _render_setup(template_name, dictionary=dictionary, context_instance=context_instance)
+ return t.iter_render(c)
+
def select_template(template_name_list):
"Given a list of template names, returns the first that can be loaded."
diff --git a/django/template/loader_tags.py b/django/template/loader_tags.py
index 4439e0b010..d12d0b55ad 100644
--- a/django/template/loader_tags.py
+++ b/django/template/loader_tags.py
@@ -15,14 +15,14 @@ class BlockNode(Node):
def __repr__(self):
return "<Block Node: %s. Contents: %r>" % (self.name, self.nodelist)
- def render(self, context):
+ def iter_render(self, context):
context.push()
# Save context in case of block.super().
self.context = context
context['block'] = self
- result = self.nodelist.render(context)
+ for chunk in self.nodelist.iter_render(context):
+ yield chunk
context.pop()
- return result
def super(self):
if self.parent:
@@ -59,7 +59,7 @@ class ExtendsNode(Node):
else:
return get_template_from_string(source, origin, parent)
- def render(self, context):
+ def iter_render(self, context):
compiled_parent = self.get_parent(context)
parent_is_child = isinstance(compiled_parent.nodelist[0], ExtendsNode)
parent_blocks = dict([(n.name, n) for n in compiled_parent.nodelist.get_nodes_by_type(BlockNode)])
@@ -79,7 +79,7 @@ class ExtendsNode(Node):
parent_block.parent = block_node.parent
parent_block.add_parent(parent_block.nodelist)
parent_block.nodelist = block_node.nodelist
- return compiled_parent.render(context)
+ return compiled_parent.iter_render(context)
class ConstantIncludeNode(Node):
def __init__(self, template_path):
@@ -91,27 +91,26 @@ class ConstantIncludeNode(Node):
raise
self.template = None
- def render(self, context):
+ def iter_render(self, context):
if self.template:
- return self.template.render(context)
- else:
- return ''
+ return self.template.iter_render(context)
+ return ()
class IncludeNode(Node):
def __init__(self, template_name):
self.template_name = template_name
- def render(self, context):
+ def iter_render(self, context):
try:
template_name = resolve_variable(self.template_name, context)
t = get_template(template_name)
- return t.render(context)
+ return t.iter_render(context)
except TemplateSyntaxError, e:
if settings.TEMPLATE_DEBUG:
raise
- return ''
+ return ()
except:
- return '' # Fail silently for invalid included templates.
+ return () # Fail silently for invalid included templates.
def do_block(parser, token):
"""
diff --git a/django/test/utils.py b/django/test/utils.py
index 46de1a896c..66fb2e66e2 100644
--- a/django/test/utils.py
+++ b/django/test/utils.py
@@ -11,12 +11,21 @@ from django.template import Template
TEST_DATABASE_PREFIX = 'test_'
def instrumented_test_render(self, context):
- """An instrumented Template render method, providing a signal
- that can be intercepted by the test system Client
-
+ """
+ An instrumented Template render method, providing a signal that can be
+ intercepted by the test system Client.
"""
dispatcher.send(signal=signals.template_rendered, sender=self, template=self, context=context)
return self.nodelist.render(context)
+
+def instrumented_test_iter_render(self, context):
+ """
+ An instrumented Template iter_render method, providing a signal that can be
+ intercepted by the test system Client.
+ """
+ for chunk in self.nodelist.iter_render(context):
+ yield chunk
+ dispatcher.send(signal=signals.template_rendered, sender=self, template=self, context=context)
class TestSMTPConnection(object):
"""A substitute SMTP connection for use during test sessions.
@@ -44,7 +53,9 @@ def setup_test_environment():
"""
Template.original_render = Template.render
+ Template.original_iter_render = Template.iter_render
Template.render = instrumented_test_render
+ Template.iter_render = instrumented_test_render
mail.original_SMTPConnection = mail.SMTPConnection
mail.SMTPConnection = TestSMTPConnection
@@ -59,7 +70,8 @@ def teardown_test_environment():
"""
Template.render = Template.original_render
- del Template.original_render
+ Template.iter_render = Template.original_iter_render
+ del Template.original_render, Template.original_iter_render
mail.SMTPConnection = mail.original_SMTPConnection
del mail.original_SMTPConnection
diff --git a/django/utils/itercompat.py b/django/utils/itercompat.py
index 370988bedb..48a2d99d3a 100644
--- a/django/utils/itercompat.py
+++ b/django/utils/itercompat.py
@@ -7,7 +7,8 @@ these implementations if necessary.
import itertools
def compat_tee(iterable):
- """Return two independent iterators from a single iterable.
+ """
+ Return two independent iterators from a single iterable.
Based on http://www.python.org/doc/2.3.5/lib/itertools-example.html
"""
@@ -25,7 +26,28 @@ def compat_tee(iterable):
next = iter(iterable).next
return gen(next), gen(next)
+def groupby(iterable, keyfunc=None):
+ """
+ Taken from http://docs.python.org/lib/itertools-functions.html
+ """
+ if keyfunc is None:
+ keyfunc = lambda x:x
+ iterable = iter(iterable)
+ l = [iterable.next()]
+ lastkey = keyfunc(l)
+ for item in iterable:
+ key = keyfunc(item)
+ if key != lastkey:
+ yield lastkey, l
+ lastkey = key
+ l = [item]
+ else:
+ l.append(item)
+ yield lastkey, l
+
if hasattr(itertools, 'tee'):
tee = itertools.tee
else:
tee = compat_tee
+if hasattr(itertools, 'groupby'):
+ groupby = itertools.groupby
diff --git a/django/views/debug.py b/django/views/debug.py
index a534f17b33..75b1a26af9 100644
--- a/django/views/debug.py
+++ b/django/views/debug.py
@@ -137,7 +137,7 @@ def technical_500_response(request, exc_type, exc_value, tb):
'template_does_not_exist': template_does_not_exist,
'loader_debug_info': loader_debug_info,
})
- return HttpResponseServerError(t.render(c), mimetype='text/html')
+ return HttpResponseServerError(t.iter_render(c), mimetype='text/html')
def technical_404_response(request, exception):
"Create a technical 404 error response. The exception should be the Http404."
@@ -160,7 +160,7 @@ def technical_404_response(request, exception):
'request_protocol': request.is_secure() and "https" or "http",
'settings': get_safe_settings(),
})
- return HttpResponseNotFound(t.render(c), mimetype='text/html')
+ return HttpResponseNotFound(t.iter_render(c), mimetype='text/html')
def empty_urlconf(request):
"Create an empty URLconf 404 error response."
@@ -168,7 +168,7 @@ def empty_urlconf(request):
c = Context({
'project_name': settings.SETTINGS_MODULE.split('.')[0]
})
- return HttpResponseNotFound(t.render(c), mimetype='text/html')
+ return HttpResponseNotFound(t.iter_render(c), mimetype='text/html')
def _get_lines_from_file(filename, lineno, context_lines, loader=None, module_name=None):
"""
diff --git a/django/views/defaults.py b/django/views/defaults.py
index 701aebabd6..aea54c963f 100644
--- a/django/views/defaults.py
+++ b/django/views/defaults.py
@@ -76,7 +76,7 @@ def page_not_found(request, template_name='404.html'):
The path of the requested URL (e.g., '/app/pages/bad_page/')
"""
t = loader.get_template(template_name) # You need to create a 404.html template.
- return http.HttpResponseNotFound(t.render(RequestContext(request, {'request_path': request.path})))
+ return http.HttpResponseNotFound(t.iter_render(RequestContext(request, {'request_path': request.path})))
def server_error(request, template_name='500.html'):
"""
@@ -86,4 +86,4 @@ def server_error(request, template_name='500.html'):
Context: None
"""
t = loader.get_template(template_name) # You need to create a 500.html template.
- return http.HttpResponseServerError(t.render(Context({})))
+ return http.HttpResponseServerError(t.iter_render(Context({})))
diff --git a/django/views/generic/create_update.py b/django/views/generic/create_update.py
index 28987f7544..d1b8e34037 100644
--- a/django/views/generic/create_update.py
+++ b/django/views/generic/create_update.py
@@ -68,7 +68,7 @@ def create_object(request, model, template_name=None,
c[key] = value()
else:
c[key] = value
- return HttpResponse(t.render(c))
+ return HttpResponse(t.iter_render(c))
def update_object(request, model, object_id=None, slug=None,
slug_field=None, template_name=None, template_loader=loader,
@@ -141,7 +141,7 @@ def update_object(request, model, object_id=None, slug=None,
c[key] = value()
else:
c[key] = value
- response = HttpResponse(t.render(c))
+ response = HttpResponse(t.iter_render(c))
populate_xheaders(request, response, model, getattr(object, object._meta.pk.attname))
return response
@@ -195,6 +195,6 @@ def delete_object(request, model, post_delete_redirect,
c[key] = value()
else:
c[key] = value
- response = HttpResponse(t.render(c))
+ response = HttpResponse(t.iter_render(c))
populate_xheaders(request, response, model, getattr(object, object._meta.pk.attname))
return response
diff --git a/django/views/generic/date_based.py b/django/views/generic/date_based.py
index d13c0293be..d4941388dd 100644
--- a/django/views/generic/date_based.py
+++ b/django/views/generic/date_based.py
@@ -44,7 +44,7 @@ def archive_index(request, queryset, date_field, num_latest=15,
c[key] = value()
else:
c[key] = value
- return HttpResponse(t.render(c), mimetype=mimetype)
+ return HttpResponse(t.iter_render(c), mimetype=mimetype)
def archive_year(request, year, queryset, date_field, template_name=None,
template_loader=loader, extra_context=None, allow_empty=False,
@@ -92,7 +92,7 @@ def archive_year(request, year, queryset, date_field, template_name=None,
c[key] = value()
else:
c[key] = value
- return HttpResponse(t.render(c), mimetype=mimetype)
+ return HttpResponse(t.iter_render(c), mimetype=mimetype)
def archive_month(request, year, month, queryset, date_field,
month_format='%b', template_name=None, template_loader=loader,
@@ -158,7 +158,7 @@ def archive_month(request, year, month, queryset, date_field,
c[key] = value()
else:
c[key] = value
- return HttpResponse(t.render(c), mimetype=mimetype)
+ return HttpResponse(t.iter_render(c), mimetype=mimetype)
def archive_week(request, year, week, queryset, date_field,
template_name=None, template_loader=loader,
@@ -206,7 +206,7 @@ def archive_week(request, year, week, queryset, date_field,
c[key] = value()
else:
c[key] = value
- return HttpResponse(t.render(c), mimetype=mimetype)
+ return HttpResponse(t.iter_render(c), mimetype=mimetype)
def archive_day(request, year, month, day, queryset, date_field,
month_format='%b', day_format='%d', template_name=None,
@@ -270,7 +270,7 @@ def archive_day(request, year, month, day, queryset, date_field,
c[key] = value()
else:
c[key] = value
- return HttpResponse(t.render(c), mimetype=mimetype)
+ return HttpResponse(t.iter_render(c), mimetype=mimetype)
def archive_today(request, **kwargs):
"""
@@ -339,6 +339,6 @@ def object_detail(request, year, month, day, queryset, date_field,
c[key] = value()
else:
c[key] = value
- response = HttpResponse(t.render(c), mimetype=mimetype)
+ response = HttpResponse(t.iter_render(c), mimetype=mimetype)
populate_xheaders(request, response, model, getattr(obj, obj._meta.pk.name))
return response
diff --git a/django/views/generic/list_detail.py b/django/views/generic/list_detail.py
index 16d55202da..b2a68d61f1 100644
--- a/django/views/generic/list_detail.py
+++ b/django/views/generic/list_detail.py
@@ -84,7 +84,7 @@ def object_list(request, queryset, paginate_by=None, page=None,
model = queryset.model
template_name = "%s/%s_list.html" % (model._meta.app_label, model._meta.object_name.lower())
t = template_loader.get_template(template_name)
- return HttpResponse(t.render(c), mimetype=mimetype)
+ return HttpResponse(t.iter_render(c), mimetype=mimetype)
def object_detail(request, queryset, object_id=None, slug=None,
slug_field=None, template_name=None, template_name_field=None,
@@ -126,6 +126,6 @@ def object_detail(request, queryset, object_id=None, slug=None,
c[key] = value()
else:
c[key] = value
- response = HttpResponse(t.render(c), mimetype=mimetype)
+ response = HttpResponse(t.iter_render(c), mimetype=mimetype)
populate_xheaders(request, response, model, getattr(obj, obj._meta.pk.name))
return response
diff --git a/django/views/generic/simple.py b/django/views/generic/simple.py
index 69a494931e..f4afb07aa0 100644
--- a/django/views/generic/simple.py
+++ b/django/views/generic/simple.py
@@ -15,7 +15,7 @@ def direct_to_template(request, template, extra_context={}, mimetype=None, **kwa
dictionary[key] = value
c = RequestContext(request, dictionary)
t = loader.get_template(template)
- return HttpResponse(t.render(c), mimetype=mimetype)
+ return HttpResponse(t.iter_render(c), mimetype=mimetype)
def redirect_to(request, url, **kwargs):
"""
diff --git a/django/views/static.py b/django/views/static.py
index 3ec4ca14a1..1e99c8c50a 100644
--- a/django/views/static.py
+++ b/django/views/static.py
@@ -92,7 +92,7 @@ def directory_index(path, fullpath):
'directory' : path + '/',
'file_list' : files,
})
- return HttpResponse(t.render(c))
+ return HttpResponse(t.iter_render(c))
def was_modified_since(header=None, mtime=0, size=0):
"""
diff --git a/docs/authentication.txt b/docs/authentication.txt
index 12b61db538..972ca42073 100644
--- a/docs/authentication.txt
+++ b/docs/authentication.txt
@@ -161,8 +161,8 @@ The ``User`` model has a custom manager that has the following helper functions:
* ``make_random_password(length=10, allowed_chars='abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789')``
Returns a random password with the given length and given string of
allowed characters. (Note that the default value of ``allowed_chars``
- doesn't contain ``"I"`` or letters that look like it, to avoid user
- confusion.
+ doesn't contain letters that can cause user confusion, including
+ ``1``, ``I`` and ``0``).
Basic usage
-----------
diff --git a/docs/newforms.txt b/docs/newforms.txt
index e37d76643a..1511791a7d 100644
--- a/docs/newforms.txt
+++ b/docs/newforms.txt
@@ -1224,7 +1224,7 @@ Form validation happens when the data is cleaned. If you want to customise
this process, there are various places you can change, each one serving a
different purpose. Thee types of cleaning methods are run during form
processing. These are normally executed when you call the ``is_valid()``
-method on a form. There are other things that can kick of cleaning and
+method on a form. There are other things that can trigger cleaning and
validation (accessing the ``errors`` attribute or calling ``full_clean()``
directly), but normally they won't be needed.
@@ -1234,7 +1234,7 @@ the ``ValidationError`` constructor. If no ``ValidationError`` is raised, the
method should return the cleaned (normalised) data as a Python object.
If you detect multiple errors during a cleaning method and wish to signal all
-of them to the form submittor, it is possible to pass a list of errors to the
+of them to the form submitter, it is possible to pass a list of errors to the
``ValidationError`` constructor.
The three types of cleaning methods are:
@@ -1293,7 +1293,7 @@ dictionary.
The previous paragraph means that if you are overriding ``Form.clean()``, you
should iterate through ``self.cleaned_data.items()``, possibly considering the
``_errors`` dictionary attribute on the form as well. In this way, you will
-already know which fields have passed thei individual validation requirements.
+already know which fields have passed their individual validation requirements.
A simple example
~~~~~~~~~~~~~~~~
diff --git a/docs/templates_python.txt b/docs/templates_python.txt
index f3e2f2c64b..c967df1a49 100644
--- a/docs/templates_python.txt
+++ b/docs/templates_python.txt
@@ -219,13 +219,13 @@ be replaced with the name of the invalid variable.
While ``TEMPLATE_STRING_IF_INVALID`` can be a useful debugging tool,
it is a bad idea to turn it on as a 'development default'.
-
+
Many templates, including those in the Admin site, rely upon the
silence of the template system when a non-existent variable is
encountered. If you assign a value other than ``''`` to
``TEMPLATE_STRING_IF_INVALID``, you will experience rendering
problems with these templates and sites.
-
+
Generally, ``TEMPLATE_STRING_IF_INVALID`` should only be enabled
in order to debug a specific template problem, then cleared
once debugging is complete.
@@ -693,14 +693,15 @@ how the compilation works and how the rendering works.
When Django compiles a template, it splits the raw template text into
''nodes''. Each node is an instance of ``django.template.Node`` and has
-a ``render()`` method. A compiled template is, simply, a list of ``Node``
-objects. When you call ``render()`` on a compiled template object, the template
-calls ``render()`` on each ``Node`` in its node list, with the given context.
-The results are all concatenated together to form the output of the template.
+either a ``render()`` or ``iter_render()`` method. A compiled template is,
+simply, a list of ``Node`` objects. When you call ``render()`` on a compiled
+template object, the template calls ``render()`` on each ``Node`` in its node
+list, with the given context. The results are all concatenated together to
+form the output of the template.
Thus, to define a custom template tag, you specify how the raw template tag is
converted into a ``Node`` (the compilation function), and what the node's
-``render()`` method does.
+``render()`` or ``iter_render()`` method does.
Writing the compilation function
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -770,7 +771,8 @@ Writing the renderer
~~~~~~~~~~~~~~~~~~~~
The second step in writing custom tags is to define a ``Node`` subclass that
-has a ``render()`` method.
+has a ``render()`` method (we will discuss the ``iter_render()`` alternative
+in `Improving rendering speed`_, below).
Continuing the above example, we need to define ``CurrentTimeNode``::
@@ -874,7 +876,7 @@ current context, available in the ``render`` method::
def __init__(self, date_to_be_formatted, format_string):
self.date_to_be_formatted = date_to_be_formatted
self.format_string = format_string
-
+
def render(self, context):
try:
actual_date = resolve_variable(self.date_to_be_formatted, context)
@@ -1175,6 +1177,48 @@ For more examples of complex rendering, see the source code for ``{% if %}``,
.. _configuration:
+Improving rendering speed
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+For most practical purposes, the ``render()`` method on a ``Node`` will be
+sufficient and the simplest way to implement a new tag. However, if your
+template tag is expected to produce large strings via ``render()``, you can
+speed up the rendering process (and reduce memory usage) using iterative
+rendering via the ``iter_render()`` method.
+
+The ``iter_render()`` method should either be an iterator that yields string
+chunks, one at a time, or a method that returns a sequence of string chunks.
+The template renderer will join the successive chunks together when creating
+the final output. The improvement over the ``render()`` method here is that
+you do not need to create one large string containing all the output of the
+``Node``, instead you can produce the output in smaller chunks.
+
+By way of example, here's a trivial ``Node`` subclass that simply returns the
+contents of a file it is given::
+
+ class FileNode(Node):
+ def __init__(self, filename):
+ self.filename = filename
+
+ def iter_render(self):
+ for line in file(self.filename):
+ yield line
+
+For very large files, the full file contents will never be read entirely into
+memory when this tag is used, which is a useful optimisation.
+
+If you define an ``iter_render()`` method on your ``Node`` subclass, you do
+not need to define a ``render()`` method. The reverse is true as well: the
+default ``Node.iter_render()`` method will call your ``render()`` method if
+necessary. A useful side-effect of this is that you can develop a new tag
+using ``render()`` and producing all the output at once, which is easy to
+debug. Then you can rewrite the method as an iterator, rename it to
+``iter_render()`` and everything will still work.
+
+It is compulsory, however, to define *either* ``render()`` or ``iter_render()``
+in your subclass. If you omit them both, a ``TypeError`` will be raised when
+the code is imported.
+
Configuring the template system in standalone mode
==================================================
@@ -1206,3 +1250,4 @@ is of obvious interest.
.. _settings file: ../settings/#using-settings-without-the-django-settings-module-environment-variable
.. _settings documentation: ../settings/
+