diff --git a/django/conf/locale/tr/LC_MESSAGES/django.mo b/django/conf/locale/tr/LC_MESSAGES/django.mo index 2d409001f4..bb3b1af83c 100644 Binary files a/django/conf/locale/tr/LC_MESSAGES/django.mo and b/django/conf/locale/tr/LC_MESSAGES/django.mo differ diff --git a/django/conf/locale/tr/LC_MESSAGES/django.po b/django/conf/locale/tr/LC_MESSAGES/django.po index dd2c592cfb..224cc7fba5 100644 --- a/django/conf/locale/tr/LC_MESSAGES/django.po +++ b/django/conf/locale/tr/LC_MESSAGES/django.po @@ -6,7 +6,7 @@ msgstr "" "Project-Id-Version: Django\n" "Report-Msgid-Bugs-To: \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 \n" "Language-Team: Turkish \n" "MIME-Version: 1.0\n" @@ -2466,3 +2466,8 @@ msgstr "evet,hayır,olabilir" #~ msgid "Have you forgotten your password?" #~ msgstr "Şifrenizi mi unuttunuz?" + +#: 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ı" diff --git a/django/contrib/auth/backends.py b/django/contrib/auth/backends.py index bd14c9b4b9..bba883ba78 100644 --- a/django/contrib/auth/backends.py +++ b/django/contrib/auth/backends.py @@ -1,14 +1,15 @@ +try: + set +except NameError: + from sets import Set as set # Python 2.3 fallback + from django.db import connection from django.contrib.auth.models import User -try: - set -except NameError: - from sets import Set as set # Python 2.3 fallback - + 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 # configurable. @@ -21,7 +22,10 @@ class ModelBackend(object): return None 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'): cursor = connection.cursor() # The SQL below works out to the following, after DB quoting: @@ -50,7 +54,7 @@ class ModelBackend(object): cursor.execute(sql, [user_obj.id]) user_obj._group_perm_cache = set(["%s.%s" % (row[0], row[1]) for row in cursor.fetchall()]) return user_obj._group_perm_cache - + def get_all_permissions(self, user_obj): if not hasattr(user_obj, '_perm_cache'): user_obj._perm_cache = set([u"%s.%s" % (p.content_type.app_label, p.codename) for p in user_obj.user_permissions.select_related()]) @@ -61,7 +65,13 @@ class ModelBackend(object): return perm in self.get_all_permissions(user_obj) 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): try: diff --git a/django/core/files/uploadedfile.py b/django/core/files/uploadedfile.py index 51cec172d4..637609d085 100644 --- a/django/core/files/uploadedfile.py +++ b/django/core/files/uploadedfile.py @@ -12,7 +12,7 @@ __all__ = ('UploadedFile', 'TemporaryUploadedFile', 'InMemoryUploadedFile') class UploadedFile(object): """ - A abstract uploadded file (``TemporaryUploadedFile`` and + A abstract uploaded file (``TemporaryUploadedFile`` and ``InMemoryUploadedFile`` are the built-in concrete subclasses). 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). """ - def __init__(self, file, field_name, file_name, content_type, charset, file_size): - super(InMemoryUploadedFile, self).__init__(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, file_size, charset) self.file = file self.field_name = field_name self.file.seek(0) diff --git a/django/core/files/uploadhandler.py b/django/core/files/uploadhandler.py index 034953972a..ab587769f7 100644 --- a/django/core/files/uploadhandler.py +++ b/django/core/files/uploadhandler.py @@ -140,9 +140,13 @@ class TemporaryFileUploadHandler(FileUploadHandler): def file_complete(self, file_size): self.file.seek(0) - return TemporaryUploadedFile(self.file, self.file_name, - self.content_type, file_size, - self.charset) + return TemporaryUploadedFile( + file = self.file, + file_name = self.file_name, + content_type = self.content_type, + file_size = file_size, + charset = self.charset + ) class MemoryFileUploadHandler(FileUploadHandler): """ @@ -182,8 +186,14 @@ class MemoryFileUploadHandler(FileUploadHandler): if not self.activated: return - return InMemoryUploadedFile(self.file, self.field_name, self.file_name, - self.content_type, self.charset, file_size) + return InMemoryUploadedFile( + 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): """ diff --git a/django/core/paginator.py b/django/core/paginator.py index 04cc4bf481..5fc6c80812 100644 --- a/django/core/paginator.py +++ b/django/core/paginator.py @@ -173,7 +173,10 @@ class ObjectPaginator(Paginator): if self._count is None: try: 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) return self._count count = property(_get_count) diff --git a/django/test/client.py b/django/test/client.py index 6313181d61..87731043a7 100644 --- a/django/test/client.py +++ b/django/test/client.py @@ -5,6 +5,7 @@ try: from cStringIO import StringIO except ImportError: from StringIO import StringIO + from django.conf import settings from django.contrib.auth import authenticate, login from django.core.handlers.base import BaseHandler @@ -22,6 +23,7 @@ from django.utils.itercompat import is_iterable BOUNDARY = 'BoUnDaRyStRiNg' MULTIPART_CONTENT = 'multipart/form-data; boundary=%s' % BOUNDARY + class FakePayload(object): """ A wrapper around StringIO that restricts what can be read since data from @@ -41,6 +43,7 @@ class FakePayload(object): self.__len -= num_bytes return content + class ClientHandler(BaseHandler): """ A HTTP Handler that can be used for testing purposes. @@ -61,7 +64,7 @@ class ClientHandler(BaseHandler): request = WSGIRequest(environ) response = self.get_response(request) - # Apply response middleware + # Apply response middleware. for middleware_method in self._response_middleware: response = middleware_method(request, response) response = self.apply_response_fixes(request, response) @@ -71,14 +74,15 @@ class ClientHandler(BaseHandler): return response 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('context',[]).append(context) def encode_multipart(boundary, data): """ - A simple method for encoding multipart POST data from a dictionary of - form values. + Encodes multipart POST data from a dictionary of form values. 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 @@ -90,7 +94,8 @@ def encode_multipart(boundary, data): if isinstance(value, file): lines.extend([ '--' + 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', '', value.read() @@ -144,13 +149,14 @@ class Client: def store_exc_info(self, *args, **kwargs): """ - Utility method that can be used to store exceptions when they are - generated by a view. + Stores exceptions when they are generated by a view. """ self.exc_info = sys.exc_info() def _session(self): - "Obtain the current session variables" + """ + Obtains the current session variables. + """ if 'django.contrib.sessions' in settings.INSTALLED_APPS: engine = __import__(settings.SESSION_ENGINE, {}, {}, ['']) 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 using the arguments to the request. """ - environ = { 'HTTP_COOKIE': self.cookies, 'PATH_INFO': '/', @@ -180,13 +185,13 @@ class Client: environ.update(self.defaults) environ.update(request) - # Curry a data dictionary into an instance of - # the template renderer callback function + # Curry a data dictionary into an instance of the template renderer + # callback function. data = {} on_template_render = curry(store_rendered_templates, data) 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) try: @@ -209,14 +214,14 @@ class Client: exc_info = self.exc_info self.exc_info = None 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.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), - # flatten the list to a single element + # flatten the list to a single element. for detail in ('template', 'context'): if data.get(detail): if len(data[detail]) == 1: @@ -226,14 +231,16 @@ class Client: else: setattr(response, detail, None) - # Update persistent cookie data + # Update persistent cookie data. if response.cookies: self.cookies.update(response.cookies) return response def get(self, path, data={}, **extra): - "Request a response from the server using GET." + """ + Requests a response from the server using GET. + """ r = { 'CONTENT_LENGTH': None, 'CONTENT_TYPE': 'text/html; charset=utf-8', @@ -246,8 +253,9 @@ class Client: return self.request(**r) 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: post_data = encode_multipart(BOUNDARY, data) else: @@ -265,30 +273,36 @@ class Client: return self.request(**r) 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 are incorrect, or the user is inactive, or if the sessions framework is not available. """ 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, {}, {}, ['']) - # Create a fake request to store login details + # Create a fake request to store login details. request = HttpRequest() request.session = engine.SessionStore() login(request, user) - # Set the cookie to represent the session - self.cookies[settings.SESSION_COOKIE_NAME] = request.session.session_key - self.cookies[settings.SESSION_COOKIE_NAME]['max-age'] = None - self.cookies[settings.SESSION_COOKIE_NAME]['path'] = '/' - self.cookies[settings.SESSION_COOKIE_NAME]['domain'] = settings.SESSION_COOKIE_DOMAIN - self.cookies[settings.SESSION_COOKIE_NAME]['secure'] = settings.SESSION_COOKIE_SECURE or None - self.cookies[settings.SESSION_COOKIE_NAME]['expires'] = None + # Set the cookie to represent the session. + session_cookie = settings.SESSION_COOKIE_NAME + self.cookies[session_cookie] = request.session.session_key + cookie_data = { + 'max-age': None, + 'path': '/', + '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() return True @@ -296,7 +310,8 @@ class Client: return False def logout(self): - """Removes the authenticated user's cookies. + """ + Removes the authenticated user's cookies. Causes the authenticated user to be logged out. """ diff --git a/docs/upload_handling.txt b/docs/upload_handling.txt index 068acf3a42..34cd085ac9 100644 --- a/docs/upload_handling.txt +++ b/docs/upload_handling.txt @@ -7,7 +7,7 @@ File Uploads 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 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. .. _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 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 ``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 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)`` Callback signaling that a new file upload is starting. This is called @@ -325,7 +325,7 @@ attributes: ``FileUploadHandler.upload_complete(self)`` 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 HTTP input. diff --git a/tests/modeltests/pagination/models.py b/tests/modeltests/pagination/models.py index 277c5961e3..1f08a32903 100644 --- a/tests/modeltests/pagination/models.py +++ b/tests/modeltests/pagination/models.py @@ -200,6 +200,29 @@ InvalidPage: ... >>> paginator.page_range [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 # ################## diff --git a/tests/regressiontests/select_related_regress/models.py b/tests/regressiontests/select_related_regress/models.py index 1688053e2d..05b851829d 100644 --- a/tests/regressiontests/select_related_regress/models.py +++ b/tests/regressiontests/select_related_regress/models.py @@ -15,10 +15,10 @@ class Device(models.Model): class Port(models.Model): device = models.ForeignKey('Device') - number = models.CharField(max_length=10) + port_number = models.CharField(max_length=10) 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): 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) >>> dev2=Device.objects.create(name="switch", building=b) >>> dev3=Device.objects.create(name="server", building=b) ->>> port1=Port.objects.create(number='4',device=dev1) ->>> port2=Port.objects.create(number='7',device=dev2) ->>> port3=Port.objects.create(number='1',device=dev3) +>>> port1=Port.objects.create(port_number='4',device=dev1) +>>> port2=Port.objects.create(port_number='7',device=dev2) +>>> port3=Port.objects.create(port_number='1',device=dev3) >>> c1=Connection.objects.create(start=port1, end=port2) >>> c2=Connection.objects.create(start=port2, end=port3)