1
0
mirror of https://github.com/django/django.git synced 2025-07-04 01:39:20 +00:00

newforms-admin: Merged from trunk up to [7829].

git-svn-id: http://code.djangoproject.com/svn/django/branches/newforms-admin@7830 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Brian Rosner 2008-07-03 15:24:08 +00:00
parent f918f9180f
commit 7dd2666bd0
10 changed files with 126 additions and 60 deletions

View File

@ -6,7 +6,7 @@ msgstr ""
"Project-Id-Version: Django\n" "Project-Id-Version: Django\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2007-03-14 01:38+0200\n" "POT-Creation-Date: 2007-03-14 01:38+0200\n"
"PO-Revision-Date: 2007-12-30 12:15+0200\n" "PO-Revision-Date: 2008-07-02 23:37+0200\n"
"Last-Translator: Can Burak Çilingir <canburak@cs.bilgi.edu.tr>\n" "Last-Translator: Can Burak Çilingir <canburak@cs.bilgi.edu.tr>\n"
"Language-Team: Turkish <bahadir@pardus.org.tr>\n" "Language-Team: Turkish <bahadir@pardus.org.tr>\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
@ -2466,3 +2466,8 @@ msgstr "evet,hayır,olabilir"
#~ msgid "Have you <a href=\"/password_reset/\">forgotten your password</a>?" #~ msgid "Have you <a href=\"/password_reset/\">forgotten your password</a>?"
#~ msgstr "<a href=\"/password_reset/\">Şifrenizi mi unuttunuz?</a>" #~ msgstr "<a href=\"/password_reset/\">Şifrenizi mi unuttunuz?</a>"
#: contrib/auth/forms.py:107
#, python-format
msgid "Password reset on %s"
msgstr "%s sitesindeki hesabınızın parolasının sıfırlanması"

View File

@ -1,14 +1,15 @@
from django.db import connection
from django.contrib.auth.models import User
try: try:
set set
except NameError: except NameError:
from sets import Set as set # Python 2.3 fallback from sets import Set as set # Python 2.3 fallback
from django.db import connection
from django.contrib.auth.models import User
class ModelBackend(object): class ModelBackend(object):
""" """
Authenticate against django.contrib.auth.models.User Authenticates against django.contrib.auth.models.User.
""" """
# TODO: Model, login attribute name and password attribute name should be # TODO: Model, login attribute name and password attribute name should be
# configurable. # configurable.
@ -21,7 +22,10 @@ class ModelBackend(object):
return None return None
def get_group_permissions(self, user_obj): def get_group_permissions(self, user_obj):
"Returns a list of permission strings that this user has through his/her groups." """
Returns a set of permission strings that this user has through his/her
groups.
"""
if not hasattr(user_obj, '_group_perm_cache'): if not hasattr(user_obj, '_group_perm_cache'):
cursor = connection.cursor() cursor = connection.cursor()
# The SQL below works out to the following, after DB quoting: # The SQL below works out to the following, after DB quoting:
@ -61,7 +65,13 @@ class ModelBackend(object):
return perm in self.get_all_permissions(user_obj) return perm in self.get_all_permissions(user_obj)
def has_module_perms(self, user_obj, app_label): def has_module_perms(self, user_obj, app_label):
return bool(len([p for p in self.get_all_permissions(user_obj) if p[:p.index('.')] == app_label])) """
Returns True if user_obj has any permissions in the given app_label.
"""
for perm in self.get_all_permissions(user_obj):
if perm[:perm.index('.')] == app_label:
return True
return False
def get_user(self, user_id): def get_user(self, user_id):
try: try:

View File

@ -12,7 +12,7 @@ __all__ = ('UploadedFile', 'TemporaryUploadedFile', 'InMemoryUploadedFile')
class UploadedFile(object): class UploadedFile(object):
""" """
A abstract uploadded file (``TemporaryUploadedFile`` and A abstract uploaded file (``TemporaryUploadedFile`` and
``InMemoryUploadedFile`` are the built-in concrete subclasses). ``InMemoryUploadedFile`` are the built-in concrete subclasses).
An ``UploadedFile`` object behaves somewhat like a file object and An ``UploadedFile`` object behaves somewhat like a file object and
@ -139,8 +139,8 @@ class InMemoryUploadedFile(UploadedFile):
""" """
A file uploaded into memory (i.e. stream-to-memory). A file uploaded into memory (i.e. stream-to-memory).
""" """
def __init__(self, file, field_name, file_name, content_type, charset, file_size): def __init__(self, file, field_name, file_name, content_type, file_size, charset):
super(InMemoryUploadedFile, self).__init__(file_name, content_type, charset, file_size) super(InMemoryUploadedFile, self).__init__(file_name, content_type, file_size, charset)
self.file = file self.file = file
self.field_name = field_name self.field_name = field_name
self.file.seek(0) self.file.seek(0)

View File

@ -140,9 +140,13 @@ class TemporaryFileUploadHandler(FileUploadHandler):
def file_complete(self, file_size): def file_complete(self, file_size):
self.file.seek(0) self.file.seek(0)
return TemporaryUploadedFile(self.file, self.file_name, return TemporaryUploadedFile(
self.content_type, file_size, file = self.file,
self.charset) file_name = self.file_name,
content_type = self.content_type,
file_size = file_size,
charset = self.charset
)
class MemoryFileUploadHandler(FileUploadHandler): class MemoryFileUploadHandler(FileUploadHandler):
""" """
@ -182,8 +186,14 @@ class MemoryFileUploadHandler(FileUploadHandler):
if not self.activated: if not self.activated:
return return
return InMemoryUploadedFile(self.file, self.field_name, self.file_name, return InMemoryUploadedFile(
self.content_type, self.charset, file_size) file = self.file,
field_name = self.field_name,
file_name = self.file_name,
content_type = self.content_type,
file_size = file_size,
charset = self.charset
)
class TemporaryFile(object): class TemporaryFile(object):
""" """

View File

@ -173,7 +173,10 @@ class ObjectPaginator(Paginator):
if self._count is None: if self._count is None:
try: try:
self._count = self.object_list.count() self._count = self.object_list.count()
except TypeError: except (AttributeError, TypeError):
# AttributeError if object_list has no count() method.
# TypeError if object_list.count() requires arguments
# (i.e. is of type list).
self._count = len(self.object_list) self._count = len(self.object_list)
return self._count return self._count
count = property(_get_count) count = property(_get_count)

View File

@ -5,6 +5,7 @@ try:
from cStringIO import StringIO from cStringIO import StringIO
except ImportError: except ImportError:
from StringIO import StringIO from StringIO import StringIO
from django.conf import settings from django.conf import settings
from django.contrib.auth import authenticate, login from django.contrib.auth import authenticate, login
from django.core.handlers.base import BaseHandler from django.core.handlers.base import BaseHandler
@ -22,6 +23,7 @@ from django.utils.itercompat import is_iterable
BOUNDARY = 'BoUnDaRyStRiNg' BOUNDARY = 'BoUnDaRyStRiNg'
MULTIPART_CONTENT = 'multipart/form-data; boundary=%s' % BOUNDARY MULTIPART_CONTENT = 'multipart/form-data; boundary=%s' % BOUNDARY
class FakePayload(object): class FakePayload(object):
""" """
A wrapper around StringIO that restricts what can be read since data from A wrapper around StringIO that restricts what can be read since data from
@ -41,6 +43,7 @@ class FakePayload(object):
self.__len -= num_bytes self.__len -= num_bytes
return content return content
class ClientHandler(BaseHandler): class ClientHandler(BaseHandler):
""" """
A HTTP Handler that can be used for testing purposes. A HTTP Handler that can be used for testing purposes.
@ -61,7 +64,7 @@ class ClientHandler(BaseHandler):
request = WSGIRequest(environ) request = WSGIRequest(environ)
response = self.get_response(request) response = self.get_response(request)
# Apply response middleware # Apply response middleware.
for middleware_method in self._response_middleware: for middleware_method in self._response_middleware:
response = middleware_method(request, response) response = middleware_method(request, response)
response = self.apply_response_fixes(request, response) response = self.apply_response_fixes(request, response)
@ -71,14 +74,15 @@ class ClientHandler(BaseHandler):
return response return response
def store_rendered_templates(store, signal, sender, template, context): def store_rendered_templates(store, signal, sender, template, context):
"A utility function for storing templates and contexts that are rendered" """
Stores templates and contexts that are rendered.
"""
store.setdefault('template',[]).append(template) store.setdefault('template',[]).append(template)
store.setdefault('context',[]).append(context) store.setdefault('context',[]).append(context)
def encode_multipart(boundary, data): def encode_multipart(boundary, data):
""" """
A simple method for encoding multipart POST data from a dictionary of Encodes multipart POST data from a dictionary of form values.
form values.
The key will be used as the form data name; the value will be transmitted The key will be used as the form data name; the value will be transmitted
as content. If the value is a file, the contents of the file will be sent as content. If the value is a file, the contents of the file will be sent
@ -90,7 +94,8 @@ def encode_multipart(boundary, data):
if isinstance(value, file): if isinstance(value, file):
lines.extend([ lines.extend([
'--' + boundary, '--' + boundary,
'Content-Disposition: form-data; name="%s"; filename="%s"' % (to_str(key), to_str(os.path.basename(value.name))), 'Content-Disposition: form-data; name="%s"; filename="%s"' \
% (to_str(key), to_str(os.path.basename(value.name))),
'Content-Type: application/octet-stream', 'Content-Type: application/octet-stream',
'', '',
value.read() value.read()
@ -144,13 +149,14 @@ class Client:
def store_exc_info(self, *args, **kwargs): def store_exc_info(self, *args, **kwargs):
""" """
Utility method that can be used to store exceptions when they are Stores exceptions when they are generated by a view.
generated by a view.
""" """
self.exc_info = sys.exc_info() self.exc_info = sys.exc_info()
def _session(self): def _session(self):
"Obtain the current session variables" """
Obtains the current session variables.
"""
if 'django.contrib.sessions' in settings.INSTALLED_APPS: if 'django.contrib.sessions' in settings.INSTALLED_APPS:
engine = __import__(settings.SESSION_ENGINE, {}, {}, ['']) engine = __import__(settings.SESSION_ENGINE, {}, {}, [''])
cookie = self.cookies.get(settings.SESSION_COOKIE_NAME, None) cookie = self.cookies.get(settings.SESSION_COOKIE_NAME, None)
@ -166,7 +172,6 @@ class Client:
Assumes defaults for the query environment, which can be overridden Assumes defaults for the query environment, which can be overridden
using the arguments to the request. using the arguments to the request.
""" """
environ = { environ = {
'HTTP_COOKIE': self.cookies, 'HTTP_COOKIE': self.cookies,
'PATH_INFO': '/', 'PATH_INFO': '/',
@ -180,13 +185,13 @@ class Client:
environ.update(self.defaults) environ.update(self.defaults)
environ.update(request) environ.update(request)
# Curry a data dictionary into an instance of # Curry a data dictionary into an instance of the template renderer
# the template renderer callback function # callback function.
data = {} data = {}
on_template_render = curry(store_rendered_templates, data) on_template_render = curry(store_rendered_templates, data)
dispatcher.connect(on_template_render, signal=signals.template_rendered) dispatcher.connect(on_template_render, signal=signals.template_rendered)
# Capture exceptions created by the handler # Capture exceptions created by the handler.
dispatcher.connect(self.store_exc_info, signal=got_request_exception) dispatcher.connect(self.store_exc_info, signal=got_request_exception)
try: try:
@ -210,13 +215,13 @@ class Client:
self.exc_info = None self.exc_info = None
raise exc_info[1], None, exc_info[2] raise exc_info[1], None, exc_info[2]
# Save the client and request that stimulated the response # Save the client and request that stimulated the response.
response.client = self response.client = self
response.request = request response.request = request
# Add any rendered template detail to the response # Add any rendered template detail to the response.
# If there was only one template rendered (the most likely case), # If there was only one template rendered (the most likely case),
# flatten the list to a single element # flatten the list to a single element.
for detail in ('template', 'context'): for detail in ('template', 'context'):
if data.get(detail): if data.get(detail):
if len(data[detail]) == 1: if len(data[detail]) == 1:
@ -226,14 +231,16 @@ class Client:
else: else:
setattr(response, detail, None) setattr(response, detail, None)
# Update persistent cookie data # Update persistent cookie data.
if response.cookies: if response.cookies:
self.cookies.update(response.cookies) self.cookies.update(response.cookies)
return response return response
def get(self, path, data={}, **extra): def get(self, path, data={}, **extra):
"Request a response from the server using GET." """
Requests a response from the server using GET.
"""
r = { r = {
'CONTENT_LENGTH': None, 'CONTENT_LENGTH': None,
'CONTENT_TYPE': 'text/html; charset=utf-8', 'CONTENT_TYPE': 'text/html; charset=utf-8',
@ -246,8 +253,9 @@ class Client:
return self.request(**r) return self.request(**r)
def post(self, path, data={}, content_type=MULTIPART_CONTENT, **extra): def post(self, path, data={}, content_type=MULTIPART_CONTENT, **extra):
"Request a response from the server using POST." """
Requests a response from the server using POST.
"""
if content_type is MULTIPART_CONTENT: if content_type is MULTIPART_CONTENT:
post_data = encode_multipart(BOUNDARY, data) post_data = encode_multipart(BOUNDARY, data)
else: else:
@ -265,30 +273,36 @@ class Client:
return self.request(**r) return self.request(**r)
def login(self, **credentials): def login(self, **credentials):
"""Set the Client to appear as if it has sucessfully logged into a site. """
Sets the Client to appear as if it has successfully logged into a site.
Returns True if login is possible; False if the provided credentials Returns True if login is possible; False if the provided credentials
are incorrect, or the user is inactive, or if the sessions framework is are incorrect, or the user is inactive, or if the sessions framework is
not available. not available.
""" """
user = authenticate(**credentials) user = authenticate(**credentials)
if user and user.is_active and 'django.contrib.sessions' in settings.INSTALLED_APPS: if user and user.is_active \
and 'django.contrib.sessions' in settings.INSTALLED_APPS:
engine = __import__(settings.SESSION_ENGINE, {}, {}, ['']) engine = __import__(settings.SESSION_ENGINE, {}, {}, [''])
# Create a fake request to store login details # Create a fake request to store login details.
request = HttpRequest() request = HttpRequest()
request.session = engine.SessionStore() request.session = engine.SessionStore()
login(request, user) login(request, user)
# Set the cookie to represent the session # Set the cookie to represent the session.
self.cookies[settings.SESSION_COOKIE_NAME] = request.session.session_key session_cookie = settings.SESSION_COOKIE_NAME
self.cookies[settings.SESSION_COOKIE_NAME]['max-age'] = None self.cookies[session_cookie] = request.session.session_key
self.cookies[settings.SESSION_COOKIE_NAME]['path'] = '/' cookie_data = {
self.cookies[settings.SESSION_COOKIE_NAME]['domain'] = settings.SESSION_COOKIE_DOMAIN 'max-age': None,
self.cookies[settings.SESSION_COOKIE_NAME]['secure'] = settings.SESSION_COOKIE_SECURE or None 'path': '/',
self.cookies[settings.SESSION_COOKIE_NAME]['expires'] = None 'domain': settings.SESSION_COOKIE_DOMAIN,
'secure': settings.SESSION_COOKIE_SECURE or None,
'expires': None,
}
self.cookies[session_cookie].update(cookie_data)
# Save the session values # Save the session values.
request.session.save() request.session.save()
return True return True
@ -296,7 +310,8 @@ class Client:
return False return False
def logout(self): def logout(self):
"""Removes the authenticated user's cookies. """
Removes the authenticated user's cookies.
Causes the authenticated user to be logged out. Causes the authenticated user to be logged out.
""" """

View File

@ -7,7 +7,7 @@ File Uploads
Most Web sites wouldn't be complete without a way to upload files. When Django Most Web sites wouldn't be complete without a way to upload files. When Django
handles a file upload, the file data ends up placed in ``request.FILES`` (for handles a file upload, the file data ends up placed in ``request.FILES`` (for
more on the ``request`` object see the documentation for `request and response more on the ``request`` object see the documentation for `request and response
objects`_). This document explains how files are stored on disk an in memory, objects`_). This document explains how files are stored on disk and in memory,
and how to customize the default behavior. and how to customize the default behavior.
.. _request and response objects: ../request_response/#attributes .. _request and response objects: ../request_response/#attributes
@ -72,7 +72,7 @@ methods to access the uploaded content:
reading in multiple chunks. By default this will be any file reading in multiple chunks. By default this will be any file
larger than 2.5 megabytes, but that's configurable; see below. larger than 2.5 megabytes, but that's configurable; see below.
``UploadedFile.chunks()`` ``UploadedFile.chunk()``
A generator returning chunks of the file. If ``multiple_chunks()`` is A generator returning chunks of the file. If ``multiple_chunks()`` is
``True``, you should use this method in a loop instead of ``read()``. ``True``, you should use this method in a loop instead of ``read()``.
@ -299,7 +299,7 @@ attributes:
multiple chunk sizes provided by multiple handlers, Django will use the multiple chunk sizes provided by multiple handlers, Django will use the
smallest chunk size defined by any handler. smallest chunk size defined by any handler.
The default is 64*2\ :sup:`10` bytes, or 64 Kb. The default is 64*2\ :sup:`10` bytes, or 64 KB.
``FileUploadHandler.new_file(self, field_name, file_name, content_type, content_length, charset)`` ``FileUploadHandler.new_file(self, field_name, file_name, content_type, content_length, charset)``
Callback signaling that a new file upload is starting. This is called Callback signaling that a new file upload is starting. This is called
@ -325,7 +325,7 @@ attributes:
``FileUploadHandler.upload_complete(self)`` ``FileUploadHandler.upload_complete(self)``
Callback signaling that the entire upload (all files) has completed. Callback signaling that the entire upload (all files) has completed.
``FileUploadHandler.``handle_raw_input(self, input_data, META, content_length, boundary, encoding)`` ``FileUploadHandler.handle_raw_input(self, input_data, META, content_length, boundary, encoding)``
Allows the handler to completely override the parsing of the raw Allows the handler to completely override the parsing of the raw
HTTP input. HTTP input.

View File

@ -200,6 +200,29 @@ InvalidPage: ...
>>> paginator.page_range >>> paginator.page_range
[1] [1]
# ObjectPaginator can be passed lists too.
>>> paginator = ObjectPaginator([1, 2, 3], 5)
>>> paginator.hits
3
>>> paginator.pages
1
>>> paginator.page_range
[1]
# ObjectPaginator can be passed other objects with a count() method.
>>> class Container:
... def __len__(self):
... return 42
>>> paginator = ObjectPaginator(Container(), 10)
>>> paginator.hits
42
>>> paginator.pages
5
>>> paginator.page_range
[1, 2, 3, 4, 5]
################## ##################
# Orphan support # # Orphan support #
################## ##################

View File

@ -15,10 +15,10 @@ class Device(models.Model):
class Port(models.Model): class Port(models.Model):
device = models.ForeignKey('Device') device = models.ForeignKey('Device')
number = models.CharField(max_length=10) port_number = models.CharField(max_length=10)
def __unicode__(self): def __unicode__(self):
return u"%s/%s" % (self.device.name, self.number) return u"%s/%s" % (self.device.name, self.port_number)
class Connection(models.Model): class Connection(models.Model):
start = models.ForeignKey(Port, related_name='connection_start', start = models.ForeignKey(Port, related_name='connection_start',
@ -38,9 +38,9 @@ the "connections = ..." queries here should give the same results.
>>> dev1=Device.objects.create(name="router", building=b) >>> dev1=Device.objects.create(name="router", building=b)
>>> dev2=Device.objects.create(name="switch", building=b) >>> dev2=Device.objects.create(name="switch", building=b)
>>> dev3=Device.objects.create(name="server", building=b) >>> dev3=Device.objects.create(name="server", building=b)
>>> port1=Port.objects.create(number='4',device=dev1) >>> port1=Port.objects.create(port_number='4',device=dev1)
>>> port2=Port.objects.create(number='7',device=dev2) >>> port2=Port.objects.create(port_number='7',device=dev2)
>>> port3=Port.objects.create(number='1',device=dev3) >>> port3=Port.objects.create(port_number='1',device=dev3)
>>> c1=Connection.objects.create(start=port1, end=port2) >>> c1=Connection.objects.create(start=port1, end=port2)
>>> c2=Connection.objects.create(start=port2, end=port3) >>> c2=Connection.objects.create(start=port2, end=port3)