mirror of
https://github.com/django/django.git
synced 2025-07-04 09:49:12 +00:00
newforms-admin: Merged to [5595]
git-svn-id: http://code.djangoproject.com/svn/django/branches/newforms-admin@5596 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
160dac766c
commit
7ed1a91968
1
AUTHORS
1
AUTHORS
@ -235,6 +235,7 @@ answer newbie questions, and generally made Django that much better:
|
||||
Joe Topjian <http://joe.terrarum.net/geek/code/python/django/>
|
||||
torne-django@wolfpuppy.org.uk
|
||||
Karen Tracey <graybark@bellsouth.net>
|
||||
tstromberg@google.com
|
||||
Makoto Tsuyuki <mtsuyuki@gmail.com>
|
||||
tt@gurgle.no
|
||||
Amit Upadhyay
|
||||
|
@ -267,7 +267,7 @@ class AnonymousUser(object):
|
||||
pass
|
||||
|
||||
def __str__(self):
|
||||
return _('AnonymousUser')
|
||||
return 'AnonymousUser'
|
||||
|
||||
def __eq__(self, other):
|
||||
return isinstance(other, self.__class__)
|
||||
|
@ -37,6 +37,7 @@ class SessionWrapper(object):
|
||||
return self._session.get(key, default)
|
||||
|
||||
def pop(self, key, *args):
|
||||
self.modified = self.modified or key in self._session
|
||||
return self._session.pop(key, *args)
|
||||
|
||||
def set_test_cookie(self):
|
||||
|
@ -5,8 +5,24 @@ Inject data into the session cache.
|
||||
>>> s._session_cache = {}
|
||||
>>> s._session_cache['some key'] = 'exists'
|
||||
|
||||
>>> s.accessed
|
||||
False
|
||||
>>> s.modified
|
||||
False
|
||||
|
||||
>>> s.pop('non existant key', 'does not exist')
|
||||
'does not exist'
|
||||
>>> s.accessed
|
||||
True
|
||||
>>> s.modified
|
||||
False
|
||||
|
||||
>>> s.pop('some key')
|
||||
'exists'
|
||||
>>> s.accessed
|
||||
True
|
||||
>>> s.modified
|
||||
True
|
||||
|
||||
>>> s.pop('some key', 'does not exist')
|
||||
'does not exist'
|
||||
|
@ -62,22 +62,23 @@ def make_msgid(idstring=None):
|
||||
class BadHeaderError(ValueError):
|
||||
pass
|
||||
|
||||
class SafeHeaderMixin(object):
|
||||
class SafeMIMEText(MIMEText):
|
||||
def __setitem__(self, name, val):
|
||||
"Forbids multi-line headers, to prevent header injection."
|
||||
if '\n' in val or '\r' in val:
|
||||
raise BadHeaderError, "Header values can't contain newlines (got %r for header %r)" % (val, name)
|
||||
if name == "Subject":
|
||||
val = Header(val, settings.DEFAULT_CHARSET)
|
||||
# Note: using super() here is safe; any __setitem__ overrides must use
|
||||
# the same argument signature.
|
||||
super(SafeHeaderMixin, self).__setitem__(name, val)
|
||||
MIMEText.__setitem__(self, name, val)
|
||||
|
||||
class SafeMIMEText(MIMEText, SafeHeaderMixin):
|
||||
pass
|
||||
|
||||
class SafeMIMEMultipart(MIMEMultipart, SafeHeaderMixin):
|
||||
pass
|
||||
class SafeMIMEMultipart(MIMEMultipart):
|
||||
def __setitem__(self, name, val):
|
||||
"Forbids multi-line headers, to prevent header injection."
|
||||
if '\n' in val or '\r' in val:
|
||||
raise BadHeaderError, "Header values can't contain newlines (got %r for header %r)" % (val, name)
|
||||
if name == "Subject":
|
||||
val = Header(val, settings.DEFAULT_CHARSET)
|
||||
MIMEMultipart.__setitem__(self, name, val)
|
||||
|
||||
class SMTPConnection(object):
|
||||
"""
|
||||
|
@ -832,9 +832,15 @@ def startproject(project_name, directory):
|
||||
sys.stderr.write(style.ERROR("Error: '%r' conflicts with the name of an existing Python module and cannot be used as a project name. Please try another name.\n" % project_name))
|
||||
sys.exit(1)
|
||||
_start_helper('project', project_name, directory)
|
||||
|
||||
# Create a random SECRET_KEY hash, and put it in the main settings.
|
||||
main_settings_file = os.path.join(directory, project_name, 'settings.py')
|
||||
settings_contents = open(main_settings_file, 'r').read()
|
||||
|
||||
# If settings.py was copied from a read-only source, make it writeable.
|
||||
if not os.access(main_settings_file, os.W_OK):
|
||||
os.chmod(main_settings_file, 0600)
|
||||
|
||||
fp = open(main_settings_file, 'w')
|
||||
secret_key = ''.join([choice('abcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*(-_=+)') for i in range(50)])
|
||||
settings_contents = re.sub(r"(?<=SECRET_KEY = ')'", secret_key + "'", settings_contents)
|
||||
|
@ -482,17 +482,18 @@ class ComboField(Field):
|
||||
|
||||
class MultiValueField(Field):
|
||||
"""
|
||||
A Field that is composed of multiple Fields.
|
||||
|
||||
Its clean() method takes a "decompressed" list of values. Each value in
|
||||
A Field that aggregates the logic of multiple Fields.
|
||||
|
||||
Its clean() method takes a "decompressed" list of values, which are then
|
||||
cleaned into a single value according to self.fields. Each value in
|
||||
this list is cleaned by the corresponding field -- the first value is
|
||||
cleaned by the first field, the second value is cleaned by the second
|
||||
field, etc. Once all fields are cleaned, the list of clean values is
|
||||
"compressed" into a single value.
|
||||
|
||||
Subclasses should implement compress(), which specifies how a list of
|
||||
valid values should be converted to a single value. Subclasses should not
|
||||
have to implement clean().
|
||||
Subclasses should not have to implement clean(). Instead, they must
|
||||
implement compress(), which takes a list of valid values and returns a
|
||||
"compressed" version of those values -- a single value.
|
||||
|
||||
You'll probably want to use this with MultiWidget.
|
||||
"""
|
||||
|
@ -304,19 +304,28 @@ class MultiWidget(Widget):
|
||||
"""
|
||||
A widget that is composed of multiple widgets.
|
||||
|
||||
Its render() method takes a "decompressed" list of values, not a single
|
||||
value. Each value in this list is rendered in the corresponding widget --
|
||||
the first value is rendered in the first widget, the second value is
|
||||
rendered in the second widget, etc.
|
||||
Its render() method is different than other widgets', because it has to
|
||||
figure out how to split a single value for display in multiple widgets.
|
||||
The ``value`` argument can be one of two things:
|
||||
|
||||
Subclasses should implement decompress(), which specifies how a single
|
||||
value should be converted to a list of values. Subclasses should not
|
||||
have to implement clean().
|
||||
* A list.
|
||||
* A normal value (e.g., a string) that has been "compressed" from
|
||||
a list of values.
|
||||
|
||||
In the second case -- i.e., if the value is NOT a list -- render() will
|
||||
first "decompress" the value into a list before rendering it. It does so by
|
||||
calling the decompress() method, which MultiWidget subclasses must
|
||||
implement. This method takes a single "compressed" value and returns a
|
||||
list.
|
||||
|
||||
When render() does its HTML rendering, each value in the list is rendered
|
||||
with the corresponding widget -- the first value is rendered in the first
|
||||
widget, the second value is rendered in the second widget, etc.
|
||||
|
||||
Subclasses may implement format_output(), which takes the list of rendered
|
||||
widgets and returns HTML that formats them any way you'd like.
|
||||
widgets and returns a string of HTML that formats them any way you'd like.
|
||||
|
||||
You'll probably want to use this with MultiValueField.
|
||||
You'll probably want to use this class with MultiValueField.
|
||||
"""
|
||||
def __init__(self, widgets, attrs=None):
|
||||
self.widgets = [isinstance(w, type) and w() or w for w in widgets]
|
||||
@ -351,6 +360,13 @@ class MultiWidget(Widget):
|
||||
return [widget.value_from_datadict(data, name + '_%s' % i) for i, widget in enumerate(self.widgets)]
|
||||
|
||||
def format_output(self, rendered_widgets):
|
||||
"""
|
||||
Given a list of rendered widgets (as strings), returns a Unicode string
|
||||
representing the HTML for the whole lot.
|
||||
|
||||
This hook allows you to format the HTML design of the widgets, if
|
||||
needed.
|
||||
"""
|
||||
return u''.join(rendered_widgets)
|
||||
|
||||
def decompress(self, value):
|
||||
|
@ -21,7 +21,7 @@ def shortcut(request, content_type_id, object_id):
|
||||
# if necessary.
|
||||
|
||||
# If the object actually defines a domain, we're done.
|
||||
if absurl.startswith('http://'):
|
||||
if absurl.startswith('http://') or absurl.startswith('https://'):
|
||||
return http.HttpResponseRedirect(absurl)
|
||||
|
||||
object_domain = None
|
||||
@ -61,7 +61,8 @@ def shortcut(request, content_type_id, object_id):
|
||||
# If all that malarkey found an object domain, use it; otherwise fall back
|
||||
# to whatever get_absolute_url() returned.
|
||||
if object_domain is not None:
|
||||
return http.HttpResponseRedirect('http://%s%s' % (object_domain, absurl))
|
||||
protocol = request.is_secure() and 'https' or 'http'
|
||||
return http.HttpResponseRedirect('%s://%s%s' % (protocol, object_domain, absurl))
|
||||
else:
|
||||
return http.HttpResponseRedirect(absurl)
|
||||
|
||||
|
@ -5,6 +5,7 @@ This demonstrates features of the database API.
|
||||
"""
|
||||
|
||||
from django.db import models
|
||||
from django.conf import settings
|
||||
|
||||
class Article(models.Model):
|
||||
headline = models.CharField(maxlength=100)
|
||||
@ -263,14 +264,14 @@ TypeError: Cannot resolve keyword 'headline__starts' into field. Choices are: id
|
||||
>>> a3.save()
|
||||
>>> a4 = Article(pub_date=now, headline='fooo')
|
||||
>>> a4.save()
|
||||
>>> a5 = Article(pub_date=now, headline='Foo')
|
||||
>>> a5 = Article(pub_date=now, headline='hey-Foo')
|
||||
>>> a5.save()
|
||||
|
||||
# zero-or-more
|
||||
>>> Article.objects.filter(headline__regex=r'fo*')
|
||||
[<Article: f>, <Article: fo>, <Article: foo>, <Article: fooo>]
|
||||
>>> Article.objects.filter(headline__iregex=r'fo*')
|
||||
[<Article: Foo>, <Article: f>, <Article: fo>, <Article: foo>, <Article: fooo>]
|
||||
[<Article: f>, <Article: fo>, <Article: foo>, <Article: fooo>, <Article: hey-Foo>]
|
||||
|
||||
# one-or-more
|
||||
>>> Article.objects.filter(headline__regex=r'fo+')
|
||||
@ -283,39 +284,39 @@ TypeError: Cannot resolve keyword 'headline__starts' into field. Choices are: id
|
||||
# and some more:
|
||||
>>> a6 = Article(pub_date=now, headline='bar')
|
||||
>>> a6.save()
|
||||
>>> a7 = Article(pub_date=now, headline='Bar')
|
||||
>>> a7 = Article(pub_date=now, headline='AbBa')
|
||||
>>> a7.save()
|
||||
>>> a8 = Article(pub_date=now, headline='baz')
|
||||
>>> a8.save()
|
||||
>>> a9 = Article(pub_date=now, headline='baZ')
|
||||
>>> a9 = Article(pub_date=now, headline='baxZ')
|
||||
>>> a9.save()
|
||||
|
||||
# leading anchor
|
||||
>>> Article.objects.filter(headline__regex=r'^b')
|
||||
[<Article: baZ>, <Article: bar>, <Article: baz>]
|
||||
>>> Article.objects.filter(headline__iregex=r'^b')
|
||||
[<Article: Bar>, <Article: baZ>, <Article: bar>, <Article: baz>]
|
||||
[<Article: bar>, <Article: baxZ>, <Article: baz>]
|
||||
>>> Article.objects.filter(headline__iregex=r'^a')
|
||||
[<Article: AbBa>]
|
||||
|
||||
# trailing anchor
|
||||
>>> Article.objects.filter(headline__regex=r'z$')
|
||||
[<Article: baz>]
|
||||
>>> Article.objects.filter(headline__iregex=r'z$')
|
||||
[<Article: baZ>, <Article: baz>]
|
||||
[<Article: baxZ>, <Article: baz>]
|
||||
|
||||
# character sets
|
||||
>>> Article.objects.filter(headline__regex=r'ba[rz]')
|
||||
[<Article: bar>, <Article: baz>]
|
||||
>>> Article.objects.filter(headline__regex=r'ba[RZ]')
|
||||
[<Article: baZ>]
|
||||
>>> Article.objects.filter(headline__iregex=r'ba[RZ]')
|
||||
[<Article: Bar>, <Article: baZ>, <Article: bar>, <Article: baz>]
|
||||
>>> Article.objects.filter(headline__regex=r'ba.[RxZ]')
|
||||
[<Article: baxZ>]
|
||||
>>> Article.objects.filter(headline__iregex=r'ba[RxZ]')
|
||||
[<Article: bar>, <Article: baxZ>, <Article: baz>]
|
||||
|
||||
# and yet more:
|
||||
>>> a10 = Article(pub_date=now, headline='foobar')
|
||||
>>> a10.save()
|
||||
>>> a11 = Article(pub_date=now, headline='foobaz')
|
||||
>>> a11.save()
|
||||
>>> a12 = Article(pub_date=now, headline='FooBarBaz')
|
||||
>>> a12 = Article(pub_date=now, headline='ooF')
|
||||
>>> a12.save()
|
||||
>>> a13 = Article(pub_date=now, headline='foobarbaz')
|
||||
>>> a13.save()
|
||||
@ -323,26 +324,28 @@ TypeError: Cannot resolve keyword 'headline__starts' into field. Choices are: id
|
||||
>>> a14.save()
|
||||
>>> a15 = Article(pub_date=now, headline='barfoobaz')
|
||||
>>> a15.save()
|
||||
>>> a16 = Article(pub_date=now, headline='BAZBARFOO')
|
||||
>>> a16 = Article(pub_date=now, headline='bazbaRFOO')
|
||||
>>> a16.save()
|
||||
|
||||
# alternation
|
||||
>>> Article.objects.filter(headline__regex=r'foo(bar|baz)')
|
||||
>>> Article.objects.filter(headline__regex=r'oo(f|b)')
|
||||
[<Article: barfoobaz>, <Article: foobar>, <Article: foobarbaz>, <Article: foobaz>]
|
||||
>>> Article.objects.filter(headline__iregex=r'foo(bar|baz)')
|
||||
[<Article: FooBarBaz>, <Article: barfoobaz>, <Article: foobar>, <Article: foobarbaz>, <Article: foobaz>]
|
||||
>>> Article.objects.filter(headline__regex=r'^foo(bar|baz)')
|
||||
>>> Article.objects.filter(headline__iregex=r'oo(f|b)')
|
||||
[<Article: barfoobaz>, <Article: foobar>, <Article: foobarbaz>, <Article: foobaz>, <Article: ooF>]
|
||||
>>> Article.objects.filter(headline__regex=r'^foo(f|b)')
|
||||
[<Article: foobar>, <Article: foobarbaz>, <Article: foobaz>]
|
||||
|
||||
# greedy matching
|
||||
>>> Article.objects.filter(headline__regex=r'f.*z')
|
||||
[<Article: barfoobaz>, <Article: foobarbaz>, <Article: foobaz>, <Article: zoocarfaz>]
|
||||
>>> Article.objects.filter(headline__iregex=r'f.*z')
|
||||
[<Article: FooBarBaz>, <Article: barfoobaz>, <Article: foobarbaz>, <Article: foobaz>, <Article: zoocarfaz>]
|
||||
>>> Article.objects.filter(headline__regex=r'b.*az')
|
||||
[<Article: barfoobaz>, <Article: baz>, <Article: bazbaRFOO>, <Article: foobarbaz>, <Article: foobaz>]
|
||||
>>> Article.objects.filter(headline__iregex=r'b.*ar')
|
||||
[<Article: bar>, <Article: barfoobaz>, <Article: bazbaRFOO>, <Article: foobar>, <Article: foobarbaz>]
|
||||
"""}
|
||||
|
||||
|
||||
if settings.DATABASE_ENGINE not in ('mysql', 'mysql_old'):
|
||||
__test__['API_TESTS'] += r"""
|
||||
# grouping and backreferences
|
||||
>>> Article.objects.filter(headline__regex=r'b(.).*b\1')
|
||||
[<Article: barfoobaz>, <Article: foobarbaz>]
|
||||
>>> Article.objects.filter(headline__iregex=r'b(.).*b\1')
|
||||
[<Article: BAZBARFOO>, <Article: FooBarBaz>, <Article: barfoobaz>, <Article: foobarbaz>]
|
||||
"""}
|
||||
[<Article: barfoobaz>, <Article: bazbaRFOO>, <Article: foobarbaz>]
|
||||
"""
|
||||
|
Loading…
x
Reference in New Issue
Block a user