diff --git a/django/contrib/flatpages/models.py b/django/contrib/flatpages/models.py index bc2a392121..8d0b2c0d90 100644 --- a/django/contrib/flatpages/models.py +++ b/django/contrib/flatpages/models.py @@ -4,7 +4,7 @@ from django.contrib.sites.models import Site from django.utils.translation import gettext_lazy as _ class FlatPage(models.Model): - url = models.CharField(_('URL'), maxlength=100, validator_list=[validators.isAlphaNumericURL], + url = models.CharField(_('URL'), maxlength=100, validator_list=[validators.isAlphaNumericURL], db_index=True, help_text=_("Example: '/about/contact/'. Make sure to have leading and trailing slashes.")) title = models.CharField(_('title'), maxlength=200) content = models.TextField(_('content')) diff --git a/django/template/defaulttags.py b/django/template/defaulttags.py index cf72d8f26e..30aeca1af1 100644 --- a/django/template/defaulttags.py +++ b/django/template/defaulttags.py @@ -280,6 +280,24 @@ class LoadNode(Node): def render(self, context): return '' +class LoremNode(Node): + def __init__(self, count, method, common): + self.count, self.method, self.common = count, method, common + + def render(self, context): + from django.utils.lorem_ipsum import words, paragraphs + try: + count = int(self.count.resolve(context)) + except (ValueError, TypeError): + count = 1 + if self.method == 'w': + return words(count, common=self.common) + else: + paras = paragraphs(count, common=self.common) + if self.method == 'p': + paras = ['
%s
' % p for p in paras] + return '\n\n'.join(paras) + class NowNode(Node): def __init__(self, format_string): self.format_string = format_string @@ -768,6 +786,52 @@ def load(parser, token): return LoadNode() load = register.tag(load) +#@register.tag +def lorem(parser, token): + """ + Creates random latin text useful for providing test data in templates. + + Usage format:: + + {% lorem [count] [method] [random] %} + + ``count`` is a number (or variable) containing the number of paragraphs or + words to generate (default is 1). + + ``method`` is either ``w`` for words, ``p`` for HTML paragraphs, ``b`` for + plain-text paragraph blocks (default is ``b``). + + ``random`` is the word ``random``, which if given, does not use the common + paragraph (starting "Lorem ipsum dolor sit amet, consectetuer..."). + + Examples: + * ``{% lorem %}`` will output the common "lorem ipsum" paragraph + * ``{% lorem 3 p %}`` will output the common "lorem ipsum" paragraph + and two random paragraphs each wrapped in HTML ```` tags + * ``{% lorem 2 w random %}`` will output two random latin words + """ + bits = list(token.split_contents()) + tagname = bits[0] + # Random bit + common = bits[-1] != 'random' + if not common: + bits.pop() + # Method bit + if bits[-1] in ('w', 'p', 'b'): + method = bits.pop() + else: + method = 'b' + # Count bit + if len(bits) > 1: + count = bits.pop() + else: + count = '1' + count = parser.compile_filter(count) + if len(bits) != 1: + raise TemplateSyntaxError, "Incorrect format for %r tag" % tagname + return LoremNode(count, method, common) +lorem = register.tag(lorem) + #@register.tag def now(parser, token): """ diff --git a/django/test/simple.py b/django/test/simple.py index 200f150594..fed6237929 100644 --- a/django/test/simple.py +++ b/django/test/simple.py @@ -84,5 +84,5 @@ def run_tests(module_list, verbosity=1, extra_tests=[]): teardown_test_environment() - return len(result.failures) + return len(result.failures) + len(result.errors) \ No newline at end of file diff --git a/docs/templates.txt b/docs/templates.txt index 8ab383c461..36da8dff07 100644 --- a/docs/templates.txt +++ b/docs/templates.txt @@ -625,6 +625,31 @@ Load a custom template tag set. See `Custom tag and filter libraries`_ for more information. +lorem +~~~~~ + +Display random latin text useful for providing sample data in templates. + +Usage format: ``{% lorem [count] [method] [random] %}`` + + =========== ============================================================= + Argument Description + =========== ============================================================= + ``count`` A number (or variable) containing the number of paragraphs or + words to generate (default is 1). + ``method`` Either ``w`` for words, ``p`` for HTML paragraphs or ``b`` + for plain-text paragraph blocks (default is ``b``). + ``random`` The word ``random``, which if given, does not use the common + paragraph ("Lorem ipsum dolor sit amet...") when generating + text. + +Examples: + + * ``{% lorem %}`` will output the common "lorem ipsum" paragraph. + * ``{% lorem 3 p %}`` will output the common "lorem ipsum" paragraph + and two random paragraphs each wrapped in HTML ``
`` tags. + * ``{% lorem 2 w random %}`` will output two random latin words. + now ~~~ diff --git a/docs/testing.txt b/docs/testing.txt index 31cea791d3..5b27ae6484 100644 --- a/docs/testing.txt +++ b/docs/testing.txt @@ -276,7 +276,7 @@ for testing purposes: ``status_code`` The HTTP status of the response. See RFC2616_ for a full list of HTTP status codes. - ``content`` The body of the response. The is the final page + ``content`` The body of the response. This is the final page content as rendered by the view, or any error message (such as the URL for a 302 redirect). @@ -468,7 +468,8 @@ failed:: FAILED (failures=1) -The return code for the script will indicate the number of tests that failed. +The return code for the script is the total number of failed and erroneous +tests. If all the tests pass, the return code is 0. Regardless of whether the tests pass or fail, the test database is destroyed when all the tests have been executed. diff --git a/docs/tutorial01.txt b/docs/tutorial01.txt index 56c5fa769e..0e857d09ca 100644 --- a/docs/tutorial01.txt +++ b/docs/tutorial01.txt @@ -133,8 +133,8 @@ Now, edit ``settings.py``. It's a normal Python module with module-level variables representing Django settings. Change these settings to match your database's connection parameters: - * ``DATABASE_ENGINE`` -- Either 'postgresql', 'mysql' or 'sqlite3'. - More coming soon. + * ``DATABASE_ENGINE`` -- Either 'postgresql_psycopg2', 'mysql' or 'sqlite3'. + Other backends are `also available`_. * ``DATABASE_NAME`` -- The name of your database, or the full (absolute) path to the database file if you're using SQLite. * ``DATABASE_USER`` -- Your database username (not used for SQLite). @@ -143,6 +143,8 @@ database's connection parameters: empty string if your database server is on the same physical machine (not used for SQLite). +.. _also available: ../settings/ + .. admonition:: Note If you're using PostgreSQL or MySQL, make sure you've created a database by @@ -319,7 +321,8 @@ Now Django knows ``mysite`` includes the ``polls`` app. Let's run another comman python manage.py sql polls -You should see the following (the CREATE TABLE SQL statements for the polls app):: +You should see something similar to the following (the CREATE TABLE SQL statements +for the polls app):: BEGIN; CREATE TABLE "polls_poll" ( @@ -337,6 +340,8 @@ You should see the following (the CREATE TABLE SQL statements for the polls app) Note the following: + * The exact output will vary depending on the database you are using. + * Table names are automatically generated by combining the name of the app (``polls``) and the lowercase name of the model -- ``poll`` and ``choice``. (You can override this behavior.) @@ -365,8 +370,9 @@ If you're interested, also run the following commands: * ``python manage.py validate polls`` -- Checks for any errors in the construction of your models. - * ``python manage.py sqlinitialdata polls`` -- Outputs any initial data - required for Django's admin framework and your models. + * ``python manage.py sqlcustom polls`` -- Outputs any custom SQL statements + (such as table modifications or constraints) that are defined for the + application. * ``python manage.py sqlclear polls`` -- Outputs the necessary ``DROP TABLE`` statements for this app, according to which tables already exist diff --git a/tests/regressiontests/templates/tests.py b/tests/regressiontests/templates/tests.py index 967767ee50..fab577d4df 100644 --- a/tests/regressiontests/templates/tests.py +++ b/tests/regressiontests/templates/tests.py @@ -654,6 +654,11 @@ class Templates(unittest.TestCase): 'with01': ('{% with dict.key as key %}{{ key }}{% endwith %}', {'dict': {'key':50}}, '50'), 'with02': ('{{ key }}{% with dict.key as key %}{{ key }}-{{ dict.key }}-{{ key }}{% endwith %}{{ key }}', {'dict': {'key':50}}, ('50-50-50', 'INVALID50-50-50INVALID')), + ### LOREM TAG ###################################################### + 'lorem01': ('{% lorem %}', {}, '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.'), + 'lorem02': ('{% lorem p %}', {}, '
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.
'), + 'lorem03': ('{% lorem 6 w %}', {}, 'lorem ipsum dolor sit amet consectetur'), + ### NOW TAG ######################################################## # Simple case 'now01' : ('{% now "j n Y"%}', {}, str(datetime.now().day) + ' ' + str(datetime.now().month) + ' ' + str(datetime.now().year)),