mirror of
https://github.com/django/django.git
synced 2025-07-04 01:39:20 +00:00
newforms-admin: Merged to [5300]
git-svn-id: http://code.djangoproject.com/svn/django/branches/newforms-admin@5301 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
4336591395
commit
c2cdd2d4b4
3
AUTHORS
3
AUTHORS
@ -190,7 +190,7 @@ answer newbie questions, and generally made Django that much better:
|
||||
polpak@yahoo.com
|
||||
J. Rademaker
|
||||
Michael Radziej <mir@noris.de>
|
||||
ramiro
|
||||
Ramiro Morales <rm0@gmx.net>
|
||||
Massimiliano Ravelli <massimiliano.ravelli@gmail.com>
|
||||
Brian Ray <http://brianray.chipy.org/>
|
||||
remco@diji.biz
|
||||
@ -209,6 +209,7 @@ answer newbie questions, and generally made Django that much better:
|
||||
sopel
|
||||
Wiliam Alves de Souza <wiliamsouza83@gmail.com>
|
||||
Georgi Stanojevski <glisha@gmail.com>
|
||||
Vasiliy Stavenko <stavenko@gmail.com>
|
||||
Thomas Steinacher <http://www.eggdrop.ch/>
|
||||
nowell strite
|
||||
Radek Švarz <http://www.svarz.cz/translate/>
|
||||
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@ -83,7 +83,7 @@ class FormPreview(object):
|
||||
"""
|
||||
while 1:
|
||||
try:
|
||||
f = self.form.fields[name]
|
||||
f = self.form.base_fields[name]
|
||||
except KeyError:
|
||||
break # This field name isn't being used by the form.
|
||||
name += '_'
|
||||
|
@ -1,7 +1,7 @@
|
||||
from django.core import urlresolvers
|
||||
import urllib
|
||||
|
||||
PING_URL = "http://www.google.com/webmasters/sitemaps/ping"
|
||||
PING_URL = "http://www.google.com/webmasters/tools/ping"
|
||||
|
||||
class SitemapNotFound(Exception):
|
||||
pass
|
||||
@ -29,7 +29,7 @@ def ping_google(sitemap_url=None, ping_url=PING_URL):
|
||||
|
||||
from django.contrib.sites.models import Site
|
||||
current_site = Site.objects.get_current()
|
||||
url = "%s%s" % (current_site.domain, sitemap_url)
|
||||
url = "http://%s%s" % (current_site.domain, sitemap_url)
|
||||
params = urllib.urlencode({'sitemap':url})
|
||||
urllib.urlopen("%s?%s" % (ping_url, params))
|
||||
|
||||
|
17
django/contrib/webdesign/tests.py
Normal file
17
django/contrib/webdesign/tests.py
Normal file
@ -0,0 +1,17 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
r"""
|
||||
>>> words(7)
|
||||
'lorem ipsum dolor sit amet consectetur adipisicing'
|
||||
|
||||
>>> paragraphs(1)
|
||||
['Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.']
|
||||
|
||||
"""
|
||||
|
||||
from django.contrib.webdesign.lorem_ipsum import *
|
||||
import datetime
|
||||
|
||||
if __name__ == '__main__':
|
||||
import doctest
|
||||
doctest.testmod()
|
@ -578,7 +578,7 @@ def syncdb(verbosity=1, interactive=True):
|
||||
# Install the 'initialdata' fixture, using format discovery
|
||||
load_data(['initial_data'], verbosity=verbosity)
|
||||
syncdb.help_doc = "Create the database tables for all apps in INSTALLED_APPS whose tables haven't already been created."
|
||||
syncdb.args = '[--verbosity] [--interactive]'
|
||||
syncdb.args = '[--verbosity] [--noinput]'
|
||||
|
||||
def get_admin_index(app):
|
||||
"Returns admin-index template snippet (in list form) for the given app."
|
||||
@ -672,7 +672,7 @@ The full error: """ % (app_name, app_name)) + style.ERROR_OUTPUT(str(e)) + '\n')
|
||||
else:
|
||||
print "Reset cancelled."
|
||||
reset.help_doc = "Executes ``sqlreset`` for the given app(s) in the current database."
|
||||
reset.args = '[--interactive]' + APP_ARGS
|
||||
reset.args = '[--noinput]' + APP_ARGS
|
||||
|
||||
def flush(verbosity=1, interactive=True):
|
||||
"Returns all tables in the database to the same state they were in immediately after syncdb."
|
||||
@ -733,7 +733,7 @@ The full error: """ % settings.DATABASE_NAME + style.ERROR_OUTPUT(str(e)) + '\n'
|
||||
else:
|
||||
print "Flush cancelled."
|
||||
flush.help_doc = "Executes ``sqlflush`` on the current database."
|
||||
flush.args = '[--verbosity] [--interactive]'
|
||||
flush.args = '[--verbosity] [--noinput]'
|
||||
|
||||
def _start_helper(app_or_project, name, directory, other_name=''):
|
||||
other = {'project': 'app', 'app': 'project'}[app_or_project]
|
||||
@ -1455,7 +1455,7 @@ def dump_data(app_labels, format='json', indent=None):
|
||||
except Exception, e:
|
||||
sys.stderr.write(style.ERROR("Unable to serialize database: %s\n" % e))
|
||||
dump_data.help_doc = 'Output the contents of the database as a fixture of the given format'
|
||||
dump_data.args = '[--format]' + APP_ARGS
|
||||
dump_data.args = '[--format] [--indent]' + APP_ARGS
|
||||
|
||||
# Utilities for command-line script
|
||||
|
||||
|
@ -121,9 +121,9 @@ class QueryDict(MultiValueDict):
|
||||
self._assert_mutable()
|
||||
MultiValueDict.update(self, other_dict)
|
||||
|
||||
def pop(self, key):
|
||||
def pop(self, key, *args):
|
||||
self._assert_mutable()
|
||||
return MultiValueDict.pop(self, key)
|
||||
return MultiValueDict.pop(self, key, *args)
|
||||
|
||||
def popitem(self):
|
||||
self._assert_mutable()
|
||||
|
@ -2,9 +2,10 @@
|
||||
Extra HTML Widget classes
|
||||
"""
|
||||
|
||||
import datetime
|
||||
|
||||
from django.newforms.widgets import Widget, Select
|
||||
from django.utils.dates import MONTHS
|
||||
import datetime
|
||||
|
||||
__all__ = ('SelectDateWidget',)
|
||||
|
||||
|
@ -2,14 +2,16 @@
|
||||
Field classes
|
||||
"""
|
||||
|
||||
from django.utils.translation import gettext
|
||||
from django.utils.encoding import smart_unicode
|
||||
from util import ErrorList, ValidationError
|
||||
from widgets import TextInput, PasswordInput, HiddenInput, MultipleHiddenInput, CheckboxInput, Select, NullBooleanSelect, SelectMultiple
|
||||
import datetime
|
||||
import re
|
||||
import time
|
||||
|
||||
from django.utils.translation import gettext
|
||||
from django.utils.encoding import smart_unicode
|
||||
|
||||
from util import ErrorList, ValidationError
|
||||
from widgets import TextInput, PasswordInput, HiddenInput, MultipleHiddenInput, CheckboxInput, Select, NullBooleanSelect, SelectMultiple
|
||||
|
||||
__all__ = (
|
||||
'Field', 'CharField', 'IntegerField',
|
||||
'DEFAULT_DATE_INPUT_FORMATS', 'DateField',
|
||||
|
@ -2,13 +2,15 @@
|
||||
Form classes
|
||||
"""
|
||||
|
||||
from django.utils.datastructures import SortedDict, MultiValueDict
|
||||
import copy
|
||||
|
||||
from django.utils.datastructures import SortedDict
|
||||
from django.utils.html import escape
|
||||
from django.utils.encoding import StrAndUnicode
|
||||
|
||||
from fields import Field
|
||||
from widgets import TextInput, Textarea, HiddenInput, MultipleHiddenInput
|
||||
from widgets import TextInput, Textarea
|
||||
from util import flatatt, ErrorDict, ErrorList, ValidationError
|
||||
import copy
|
||||
|
||||
__all__ = ('BaseForm', 'Form')
|
||||
|
||||
|
@ -4,13 +4,16 @@ and database field objects.
|
||||
"""
|
||||
|
||||
from django.utils.translation import gettext
|
||||
|
||||
from util import ValidationError
|
||||
from forms import BaseForm, DeclarativeFieldsMetaclass, SortedDictFromList
|
||||
from forms import BaseForm, SortedDictFromList
|
||||
from fields import Field, ChoiceField
|
||||
from widgets import Select, SelectMultiple, MultipleHiddenInput
|
||||
|
||||
__all__ = ('save_instance', 'form_for_model', 'form_for_instance', 'form_for_fields',
|
||||
'ModelChoiceField', 'ModelMultipleChoiceField')
|
||||
__all__ = (
|
||||
'save_instance', 'form_for_model', 'form_for_instance', 'form_for_fields',
|
||||
'ModelChoiceField', 'ModelMultipleChoiceField'
|
||||
)
|
||||
|
||||
def save_instance(form, instance, fields=None, fail_message='saved', commit=True):
|
||||
"""
|
||||
|
@ -1,11 +1,14 @@
|
||||
from django.conf import settings
|
||||
from django.utils.html import escape
|
||||
from django.utils.functional import Promise, lazy
|
||||
from django.utils.encoding import smart_unicode
|
||||
|
||||
# Converts a dictionary to a single string with key="value", XML-style with
|
||||
# a leading space. Assumes keys do not need to be XML-escaped.
|
||||
flatatt = lambda attrs: u''.join([u' %s="%s"' % (k, escape(v)) for k, v in attrs.items()])
|
||||
def flatatt(attrs):
|
||||
"""
|
||||
Convert a dictionary of attributes to a single string.
|
||||
The returned string will contain a leading space followed by key="value",
|
||||
XML-style pairs. It is assumed that the keys do not need to be XML-escaped.
|
||||
If the passed dictionary is empty, then return an empty string.
|
||||
"""
|
||||
return u''.join([u' %s="%s"' % (k, escape(v)) for k, v in attrs.items()])
|
||||
|
||||
class ErrorDict(dict):
|
||||
"""
|
||||
|
@ -2,24 +2,26 @@
|
||||
HTML Widget classes
|
||||
"""
|
||||
|
||||
__all__ = (
|
||||
'Widget', 'TextInput', 'PasswordInput', 'HiddenInput', 'MultipleHiddenInput',
|
||||
'FileInput', 'Textarea', 'CheckboxInput',
|
||||
'Select', 'NullBooleanSelect', 'SelectMultiple', 'RadioSelect', 'CheckboxSelectMultiple',
|
||||
'MultiWidget', 'SplitDateTimeWidget',
|
||||
)
|
||||
|
||||
from util import flatatt
|
||||
from django.utils.datastructures import MultiValueDict
|
||||
from django.utils.html import escape
|
||||
from django.utils.translation import gettext
|
||||
from django.utils.encoding import StrAndUnicode, smart_unicode
|
||||
from itertools import chain
|
||||
|
||||
try:
|
||||
set # Only available in Python 2.4+
|
||||
except NameError:
|
||||
from sets import Set as set # Python 2.3 fallback
|
||||
from itertools import chain
|
||||
|
||||
from django.utils.datastructures import MultiValueDict
|
||||
from django.utils.html import escape
|
||||
from django.utils.translation import gettext
|
||||
from django.utils.encoding import StrAndUnicode, smart_unicode
|
||||
|
||||
from util import flatatt
|
||||
|
||||
__all__ = (
|
||||
'Widget', 'TextInput', 'PasswordInput',
|
||||
'HiddenInput', 'MultipleHiddenInput',
|
||||
'FileInput', 'Textarea', 'CheckboxInput',
|
||||
'Select', 'NullBooleanSelect', 'SelectMultiple', 'RadioSelect',
|
||||
'CheckboxSelectMultiple', 'MultiWidget', 'SplitDateTimeWidget',
|
||||
)
|
||||
|
||||
class Widget(object):
|
||||
is_hidden = False # Determines whether this corresponds to an <input type="hidden">.
|
||||
|
@ -279,6 +279,15 @@ Please follow these coding standards when writing code for inclusion in Django:
|
||||
* Mark all strings for internationalization; see the `i18n documentation`_
|
||||
for details.
|
||||
|
||||
* Please don't put your name in the code you contribute. Our policy is to
|
||||
keep contributors' names in the ``AUTHORS`` file distributed with Django
|
||||
-- not scattered throughout the codebase itself. Feel free to include a
|
||||
change to the ``AUTHORS`` file in your patch if you make more than a
|
||||
single trivial change.
|
||||
|
||||
Template style
|
||||
--------------
|
||||
|
||||
* In Django template code, put one (and only one) space between the curly
|
||||
brackets and the tag contents.
|
||||
|
||||
@ -290,6 +299,9 @@ Please follow these coding standards when writing code for inclusion in Django:
|
||||
|
||||
{{foo}}
|
||||
|
||||
View style
|
||||
----------
|
||||
|
||||
* In Django views, the first parameter in a view function should be called
|
||||
``request``.
|
||||
|
||||
@ -303,11 +315,72 @@ Please follow these coding standards when writing code for inclusion in Django:
|
||||
def my_view(req, foo):
|
||||
# ...
|
||||
|
||||
* Please don't put your name in the code you contribute. Our policy is to
|
||||
keep contributors' names in the ``AUTHORS`` file distributed with Django
|
||||
-- not scattered throughout the codebase itself. Feel free to include a
|
||||
change to the ``AUTHORS`` file in your patch if you make more than a
|
||||
single trivial change.
|
||||
Model style
|
||||
-----------
|
||||
|
||||
* Field names should be all lowercase, using underscores instead of
|
||||
camelCase.
|
||||
|
||||
Do this::
|
||||
|
||||
class Person(models.Model):
|
||||
first_name = models.CharField(maxlength=20)
|
||||
last_name = models.CharField(maxlength=40)
|
||||
|
||||
Don't do this::
|
||||
|
||||
class Person(models.Model):
|
||||
FirstName = models.CharField(maxlength=20)
|
||||
Last_Name = models.CharField(maxlength=40)
|
||||
|
||||
* The ``class Meta`` should appear *after* the fields are defined, with
|
||||
a single blank line separating the fields and the class definition.
|
||||
|
||||
Do this::
|
||||
|
||||
class Person(models.Model):
|
||||
first_name = models.CharField(maxlength=20)
|
||||
last_name = models.CharField(maxlength=40)
|
||||
|
||||
class Meta:
|
||||
verbose_name_plural = 'people'
|
||||
|
||||
Don't do this::
|
||||
|
||||
class Person(models.Model):
|
||||
first_name = models.CharField(maxlength=20)
|
||||
last_name = models.CharField(maxlength=40)
|
||||
class Meta:
|
||||
verbose_name_plural = 'people'
|
||||
|
||||
Don't do this, either::
|
||||
|
||||
class Person(models.Model):
|
||||
class Meta:
|
||||
verbose_name_plural = 'people'
|
||||
|
||||
first_name = models.CharField(maxlength=20)
|
||||
last_name = models.CharField(maxlength=40)
|
||||
|
||||
* The order of model inner classes and standard methods should be as
|
||||
follows (noting that these are not all required):
|
||||
|
||||
* All database fields
|
||||
* ``class Meta``
|
||||
* ``class Admin``
|
||||
* ``def __str__()``
|
||||
* ``def save()``
|
||||
* ``def get_absolute_url()``
|
||||
* Any custom methods
|
||||
|
||||
* If ``choices`` is defined for a given model field, define the choices as
|
||||
a tuple of tuples, with an all-uppercase name, either near the top of the
|
||||
model module or just above the model class. Example::
|
||||
|
||||
GENDER_CHOICES = (
|
||||
('M', 'Male'),
|
||||
('F', 'Female'),
|
||||
)
|
||||
|
||||
Committing code
|
||||
===============
|
||||
|
@ -143,8 +143,8 @@ or ``UPDATE`` SQL statements. Specifically, when you call ``save()``, Django
|
||||
follows this algorithm:
|
||||
|
||||
* If the object's primary key attribute is set to a value that evaluates to
|
||||
``True`` (i.e., a value other than ``None`` or the empty string), Django
|
||||
executes a ``SELECT`` query to determine whether a record with the given
|
||||
``True`` (i.e., a value other than ``None`` or the empty string), Django
|
||||
executes a ``SELECT`` query to determine whether a record with the given
|
||||
primary key already exists.
|
||||
* If the record with the given primary key does already exist, Django
|
||||
executes an ``UPDATE`` query.
|
||||
@ -525,19 +525,19 @@ Examples::
|
||||
[datetime.datetime(2005, 3, 20), datetime.datetime(2005, 2, 20)]
|
||||
>>> Entry.objects.filter(headline__contains='Lennon').dates('pub_date', 'day')
|
||||
[datetime.datetime(2005, 3, 20)]
|
||||
|
||||
|
||||
``none()``
|
||||
~~~~~~~~~~
|
||||
|
||||
**New in Django development version**
|
||||
|
||||
Returns an ``EmptyQuerySet`` -- a ``QuerySet`` that always evaluates to
|
||||
Returns an ``EmptyQuerySet`` -- a ``QuerySet`` that always evaluates to
|
||||
an empty list. This can be used in cases where you know that you should
|
||||
return an empty result set and your caller is expecting a ``QuerySet``
|
||||
object (instead of returning an empty list, for example.)
|
||||
|
||||
Examples::
|
||||
|
||||
|
||||
>>> Entry.objects.none()
|
||||
[]
|
||||
|
||||
@ -610,7 +610,7 @@ follow::
|
||||
c = p.hometown # Requires a database call.
|
||||
|
||||
The ``depth`` argument is new in the Django development version.
|
||||
|
||||
|
||||
``extra(select=None, where=None, params=None, tables=None)``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@ -1136,7 +1136,7 @@ such as January 3, July 3, etc.
|
||||
isnull
|
||||
~~~~~~
|
||||
|
||||
Takes either ``True`` or ``False``, which correspond to SQL queries of
|
||||
Takes either ``True`` or ``False``, which correspond to SQL queries of
|
||||
``IS NULL`` and ``IS NOT NULL``, respectively.
|
||||
|
||||
Example::
|
||||
@ -1149,10 +1149,10 @@ SQL equivalent::
|
||||
|
||||
.. admonition:: ``__isnull=True`` vs ``__exact=None``
|
||||
|
||||
There is an important difference between ``__isnull=True`` and
|
||||
There is an important difference between ``__isnull=True`` and
|
||||
``__exact=None``. ``__exact=None`` will *always* return an empty result
|
||||
set, because SQL requires that no value is equal to ``NULL``.
|
||||
``__isnull`` determines if the field is currently holding the value
|
||||
set, because SQL requires that no value is equal to ``NULL``.
|
||||
``__isnull`` determines if the field is currently holding the value
|
||||
of ``NULL`` without performing a comparison.
|
||||
|
||||
search
|
||||
@ -1181,7 +1181,7 @@ The pk lookup shortcut
|
||||
----------------------
|
||||
|
||||
For convenience, Django provides a ``pk`` lookup type, which stands for
|
||||
"primary_key".
|
||||
"primary_key".
|
||||
|
||||
In the example ``Blog`` model, the primary key is the ``id`` field, so these
|
||||
three statements are equivalent::
|
||||
@ -1190,14 +1190,14 @@ three statements are equivalent::
|
||||
Blog.objects.get(id=14) # __exact is implied
|
||||
Blog.objects.get(pk=14) # pk implies id__exact
|
||||
|
||||
The use of ``pk`` isn't limited to ``__exact`` queries -- any query term
|
||||
The use of ``pk`` isn't limited to ``__exact`` queries -- any query term
|
||||
can be combined with ``pk`` to perform a query on the primary key of a model::
|
||||
|
||||
# Get blogs entries with id 1, 4 and 7
|
||||
Blog.objects.filter(pk__in=[1,4,7])
|
||||
# Get all blog entries with id > 14
|
||||
Blog.objects.filter(pk__gt=14)
|
||||
|
||||
Blog.objects.filter(pk__gt=14)
|
||||
|
||||
``pk`` lookups also work across joins. For example, these three statements are
|
||||
equivalent::
|
||||
|
||||
@ -1754,19 +1754,19 @@ get_object_or_404()
|
||||
-------------------
|
||||
|
||||
One common idiom to use ``get()`` and raise ``Http404`` if the
|
||||
object doesn't exist. This idiom is captured by ``get_object_or_404()``.
|
||||
This function takes a Django model as its first argument and an
|
||||
arbitrary number of keyword arguments, which it passes to the manager's
|
||||
object doesn't exist. This idiom is captured by ``get_object_or_404()``.
|
||||
This function takes a Django model as its first argument and an
|
||||
arbitrary number of keyword arguments, which it passes to the manager's
|
||||
``get()`` function. It raises ``Http404`` if the object doesn't
|
||||
exist. For example::
|
||||
|
||||
exist. For example::
|
||||
|
||||
# Get the Entry with a primary key of 3
|
||||
e = get_object_or_404(Entry, pk=3)
|
||||
|
||||
When you provide a model to this shortcut function, the default manager
|
||||
is used to execute the underlying ``get()`` query. If you don't want to
|
||||
use the default manager, or you want to search a list of related objects,
|
||||
you can provide ``get_object_or_404()`` with a manager object, instead.
|
||||
When you provide a model to this shortcut function, the default manager
|
||||
is used to execute the underlying ``get()`` query. If you don't want to
|
||||
use the default manager, or if you want to search a list of related objects,
|
||||
you can provide ``get_object_or_404()`` with a manager object instead.
|
||||
For example::
|
||||
|
||||
# Get the author of blog instance `e` with a name of 'Fred'
|
||||
@ -1779,8 +1779,8 @@ For example::
|
||||
get_list_or_404()
|
||||
-----------------
|
||||
|
||||
``get_list_or_404`` behaves the same was as ``get_object_or_404()``
|
||||
-- except the it uses using ``filter()`` instead of ``get()``. It raises
|
||||
``get_list_or_404`` behaves the same way as ``get_object_or_404()``
|
||||
-- except that it uses ``filter()`` instead of ``get()``. It raises
|
||||
``Http404`` if the list is empty.
|
||||
|
||||
Falling back to raw SQL
|
||||
|
@ -11,8 +11,8 @@ Being a Python Web framework, Django requires Python.
|
||||
|
||||
It works with any Python version 2.3 and higher.
|
||||
|
||||
Get Python at www.python.org. If you're running Linux or Mac OS X, you probably
|
||||
already have it installed.
|
||||
Get Python at http://www.python.org. If you're running Linux or Mac OS X, you
|
||||
probably already have it installed.
|
||||
|
||||
Install Apache and mod_python
|
||||
=============================
|
||||
|
@ -1759,6 +1759,15 @@ But this template code is good::
|
||||
|
||||
<a href="{{ object.get_absolute_url }}">{{ object.name }}</a>
|
||||
|
||||
.. note::
|
||||
The string you return from ``get_absolute_url()`` must contain only ASCII
|
||||
characters (required by the URI spec, `RFC 2396`_) that have been
|
||||
URL-encoded, if necessary. Code and templates using ``get_absolute_url()``
|
||||
should be able to use the result directly without needing to do any
|
||||
further processing.
|
||||
|
||||
.. _RFC 2396: http://www.ietf.org/rfc/rfc2396.txt
|
||||
|
||||
The ``permalink`` decorator
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
@ -602,6 +602,102 @@ when printed::
|
||||
>>> str(f['subject'].errors)
|
||||
''
|
||||
|
||||
Using forms in views and templates
|
||||
----------------------------------
|
||||
|
||||
Let's put this all together and use the ``ContactForm`` example in a Django
|
||||
view and template. This example view displays the contact form by default and
|
||||
validates/processes it if accessed via a POST request::
|
||||
|
||||
def contact(request):
|
||||
if request.method == 'POST':
|
||||
form = ContactForm(request.POST)
|
||||
if form.is_valid():
|
||||
# Do form processing here...
|
||||
return HttpResponseRedirect('/url/on_success/')
|
||||
else:
|
||||
form = ContactForm()
|
||||
return render_to_response('contact.html', {'form': form})
|
||||
|
||||
Simple template output
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The template, ``contact.html``, is responsible for displaying the form as HTML.
|
||||
To do this, we can use the techniques outlined in the "Outputting forms as HTML"
|
||||
section above.
|
||||
|
||||
The simplest way to display a form's HTML is to use the variable on its own,
|
||||
like this::
|
||||
|
||||
<form method="post">
|
||||
<table>{{ form }}</table>
|
||||
<input type="submit" />
|
||||
</form>
|
||||
|
||||
The above template code will display the form as an HTML table, using the
|
||||
``form.as_table()`` method explained previously. This works because Django's
|
||||
template system displays an object's ``__str__()`` value, and the ``Form``
|
||||
class' ``__str__()`` method calls its ``as_table()`` method.
|
||||
|
||||
The following is equivalent but a bit more explicit::
|
||||
|
||||
<form method="post">
|
||||
<table>{{ form.as_table }}</table>
|
||||
<input type="submit" />
|
||||
</form>
|
||||
|
||||
``form.as_ul`` and ``form.as_p`` are also available, as you may expect.
|
||||
|
||||
Note that in the above two examples, we included the ``<form>``, ``<table>``
|
||||
``<input type="submit" />``, ``</table>`` and ``</form>`` tags. The form
|
||||
convenience methods (``as_table()``, ``as_ul()`` and ``as_p()``) do not include
|
||||
that HTML.
|
||||
|
||||
Complex template output
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
As we've stressed several times, the ``as_table()``, ``as_ul()`` and ``as_p()``
|
||||
methods are just shortcuts for the common case. You can also work with the
|
||||
individual fields for complete template control over the form's design.
|
||||
|
||||
The easiest way is to iterate over the form's fields, with
|
||||
``{% for field in form %}``. For example::
|
||||
|
||||
<form method="post">
|
||||
<dl>
|
||||
{% for field in form %}
|
||||
<dt>{{ field.label }}</dt>
|
||||
<dd>{{ field }}</dd>
|
||||
{% if field.help_text %}<dd>{{ field.help_text }}</dd>{% endif %}
|
||||
{% if field.errors %}<dd class="myerrors">{{ field.errors }}</dd>{% endif %}
|
||||
{% endfor %}
|
||||
</dl>
|
||||
<input type="submit" />
|
||||
</form>
|
||||
|
||||
This iteration technique is useful if you want to apply the same HTML
|
||||
formatting to each field, or if you don't know the names of the form fields
|
||||
ahead of time. Note that the fields will be listed in the order in which
|
||||
they're defined in the ``Form`` class.
|
||||
|
||||
Alternatively, you can arrange the form's fields explicitly, by name. Do that
|
||||
by accessing ``{{ form.fieldname }}``, where ``fieldname`` is the field's name.
|
||||
For example::
|
||||
|
||||
<form method="post">
|
||||
<ul class="myformclass">
|
||||
<li>{{ form.sender.label }} {{ form.sender.label }}</li>
|
||||
<li class="helptext">{{ form.sender.help_text }}</li>
|
||||
{% if form.sender.errors %}<ul class="errorlist">{{ form.sender.errors }}</dd>{% endif %}
|
||||
|
||||
<li>{{ form.subject.label }} {{ form.subject.label }}</li>
|
||||
<li class="helptext">{{ form.subject.help_text }}</li>
|
||||
{% if form.subject.errors %}<ul class="errorlist">{{ form.subject.errors }}</dd>{% endif %}
|
||||
|
||||
...
|
||||
</ul>
|
||||
</form>
|
||||
|
||||
Subclassing forms
|
||||
-----------------
|
||||
|
||||
|
@ -1055,7 +1055,7 @@ You can tell Django to stop reporting particular 404s by tweaking the
|
||||
tuple of strings. For example::
|
||||
|
||||
IGNORABLE_404_ENDS = ('.php', '.cgi')
|
||||
IGNORABLE_404_STARTS = ('/phpmyadmin/')
|
||||
IGNORABLE_404_STARTS = ('/phpmyadmin/',)
|
||||
|
||||
In this example, a 404 to any URL ending with ``.php`` or ``.cgi`` will *not*
|
||||
be reported. Neither will any URL starting with ``/phpmyadmin/``.
|
||||
|
@ -146,7 +146,10 @@ put into those elements.
|
||||
exist, it tries calling a method ``item_link()`` in the ``Feed`` class,
|
||||
passing it a single parameter, ``item``, which is the object itself.
|
||||
Both ``get_absolute_url()`` and ``item_link()`` should return the item's
|
||||
URL as a normal Python string.
|
||||
URL as a normal Python string. As with ``get_absolute_url()``, the
|
||||
result of ``item_link()`` will be included directly in the URL, so you
|
||||
are responsible for doing all necessary URL quoting and conversion to
|
||||
ASCII inside the method itself.
|
||||
|
||||
* For the LatestEntries example above, we could have very simple feed templates:
|
||||
|
||||
|
@ -42,13 +42,13 @@ _django_completion()
|
||||
prev="${COMP_WORDS[COMP_CWORD-1]}"
|
||||
|
||||
# Standalone options
|
||||
opts="--help --settings --pythonpath --version"
|
||||
opts="--help --settings --pythonpath --noinput --noreload --format --indent --verbosity --adminmedia --version"
|
||||
# Actions
|
||||
actions="adminindex createcachetable dbshell diffsettings \
|
||||
inspectdb install reset runfcgi runserver \
|
||||
shell sql sqlall sqlclear sqlindexes sqlinitialdata \
|
||||
dumpdata flush inspectdb loaddata reset runfcgi runserver \
|
||||
shell sql sqlall sqlclear sqlcustom sqlflush sqlindexes \
|
||||
sqlreset sqlsequencereset startapp startproject \
|
||||
syncdb validate"
|
||||
syncdb test validate"
|
||||
# Action's options
|
||||
action_shell_opts="--plain"
|
||||
action_runfcgi_opts="host port socket method maxspare minspare maxchildren daemonize pidfile workdir"
|
||||
@ -84,33 +84,33 @@ _django_completion()
|
||||
esac
|
||||
else
|
||||
case ${prev} in
|
||||
adminindex|install|reset| \
|
||||
sql|sqlall|sqlclear|sqlindexes| \
|
||||
sqlinitialdata|sqlreset|sqlsequencereset)
|
||||
# App completion
|
||||
settings=""
|
||||
# If settings.py in the PWD, use that
|
||||
if [ -e settings.py ] ; then
|
||||
settings="$PWD/settings.py"
|
||||
else
|
||||
# Use the ENV variable if it is set
|
||||
if [ $DJANGO_SETTINGS_MODULE ] ; then
|
||||
settings=$DJANGO_SETTINGS_MODULE
|
||||
adminindex|dumpdata|reset| \
|
||||
sql|sqlall|sqlclear|sqlcustom|sqlindexes| \
|
||||
sqlreset|sqlsequencereset|test)
|
||||
# App completion
|
||||
settings=""
|
||||
# If settings.py in the PWD, use that
|
||||
if [ -e settings.py ] ; then
|
||||
settings="$PWD/settings.py"
|
||||
else
|
||||
# Use the ENV variable if it is set
|
||||
if [ $DJANGO_SETTINGS_MODULE ] ; then
|
||||
settings=$DJANGO_SETTINGS_MODULE
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
# Couldn't find settings so return nothing
|
||||
if [ -z $settings ] ; then
|
||||
COMPREPLY=()
|
||||
# Otherwise inspect settings.py file
|
||||
else
|
||||
apps=`sed -n "/INSTALLED_APPS = (/,/)/p" $settings | \
|
||||
grep -v "django.contrib" |
|
||||
sed -n "s/^[ ]*'\(.*\.\)*\(.*\)'.*$/\2 /pg" | \
|
||||
tr -d "\n"`
|
||||
COMPREPLY=( $(compgen -W "${apps}" -- ${cur}) )
|
||||
fi
|
||||
return 0
|
||||
;;
|
||||
# Couldn't find settings so return nothing
|
||||
if [ -z $settings ] ; then
|
||||
COMPREPLY=()
|
||||
# Otherwise inspect settings.py file
|
||||
else
|
||||
apps=`sed -n "/INSTALLED_APPS = (/,/)/p" $settings | \
|
||||
grep -v "django.contrib" |
|
||||
sed -n "s/^[ ]*'\(.*\.\)*\(.*\)'.*$/\2 /pg" | \
|
||||
tr -d "\n"`
|
||||
COMPREPLY=( $(compgen -W "${apps}" -- ${cur}) )
|
||||
fi
|
||||
return 0
|
||||
;;
|
||||
|
||||
createcachetable|dbshell|diffsettings| \
|
||||
inspectdb|runserver|startapp|startproject|syncdb| \
|
||||
|
@ -3516,6 +3516,15 @@ u'\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111'
|
||||
u'1'
|
||||
>>> smart_unicode('foo')
|
||||
u'foo'
|
||||
|
||||
# flatatt tests
|
||||
>>> from django.newforms.util import flatatt
|
||||
>>> flatatt({'id': "header"})
|
||||
u' id="header"'
|
||||
>>> flatatt({'class': "news", 'title': "Read this"})
|
||||
u' class="news" title="Read this"'
|
||||
>>> flatatt({})
|
||||
u''
|
||||
"""
|
||||
|
||||
__test__ = {
|
||||
|
@ -166,6 +166,9 @@ True
|
||||
>>> q.pop('foo')
|
||||
['bar', 'baz', 'another', 'hello']
|
||||
|
||||
>>> q.pop('foo', 'not there')
|
||||
'not there'
|
||||
|
||||
>>> q.get('foo', 'not there')
|
||||
'not there'
|
||||
|
||||
|
@ -3,11 +3,15 @@
|
||||
import os, sys, traceback
|
||||
import unittest
|
||||
|
||||
import django.contrib as contrib
|
||||
CONTRIB_DIR_NAME = 'django.contrib'
|
||||
MODEL_TESTS_DIR_NAME = 'modeltests'
|
||||
REGRESSION_TESTS_DIR_NAME = 'regressiontests'
|
||||
|
||||
TEST_DATABASE_NAME = 'django_test_db'
|
||||
TEST_TEMPLATE_DIR = 'templates'
|
||||
|
||||
CONTRIB_DIR = os.path.dirname(contrib.__file__)
|
||||
MODEL_TEST_DIR = os.path.join(os.path.dirname(__file__), MODEL_TESTS_DIR_NAME)
|
||||
REGRESSION_TEST_DIR = os.path.join(os.path.dirname(__file__), REGRESSION_TESTS_DIR_NAME)
|
||||
|
||||
@ -24,7 +28,7 @@ ALWAYS_INSTALLED_APPS = [
|
||||
|
||||
def get_test_models():
|
||||
models = []
|
||||
for loc, dirpath in (MODEL_TESTS_DIR_NAME, MODEL_TEST_DIR), (REGRESSION_TESTS_DIR_NAME, REGRESSION_TEST_DIR):
|
||||
for loc, dirpath in (MODEL_TESTS_DIR_NAME, MODEL_TEST_DIR), (REGRESSION_TESTS_DIR_NAME, REGRESSION_TEST_DIR), (CONTRIB_DIR_NAME, CONTRIB_DIR):
|
||||
for f in os.listdir(dirpath):
|
||||
if f.startswith('__init__') or f.startswith('.') or f.startswith('sql') or f.startswith('invalid'):
|
||||
continue
|
||||
@ -33,7 +37,7 @@ def get_test_models():
|
||||
|
||||
def get_invalid_models():
|
||||
models = []
|
||||
for loc, dirpath in (MODEL_TESTS_DIR_NAME, MODEL_TEST_DIR), (REGRESSION_TESTS_DIR_NAME, REGRESSION_TEST_DIR):
|
||||
for loc, dirpath in (MODEL_TESTS_DIR_NAME, MODEL_TEST_DIR), (REGRESSION_TESTS_DIR_NAME, REGRESSION_TEST_DIR), (CONTRIB_DIR_NAME, CONTRIB_DIR):
|
||||
for f in os.listdir(dirpath):
|
||||
if f.startswith('__init__') or f.startswith('.') or f.startswith('sql'):
|
||||
continue
|
||||
@ -109,8 +113,10 @@ def django_tests(verbosity, tests_to_run):
|
||||
if verbosity >= 1:
|
||||
print "Importing model %s" % model_name
|
||||
mod = load_app(model_label)
|
||||
settings.INSTALLED_APPS.append(model_label)
|
||||
test_models.append(mod)
|
||||
if mod:
|
||||
if model_label not in settings.INSTALLED_APPS:
|
||||
settings.INSTALLED_APPS.append(model_label)
|
||||
test_models.append(mod)
|
||||
except Exception, e:
|
||||
sys.stderr.write("Error while importing %s:" % model_name + ''.join(traceback.format_exception(*sys.exc_info())[1:]))
|
||||
continue
|
||||
|
Loading…
x
Reference in New Issue
Block a user