Changeset 4139
- Timestamp:
- 11/29/06 14:02:43 (2 years ago)
- Files:
-
- django/branches/multiple-db-support/AUTHORS (modified) (5 diffs)
- django/branches/multiple-db-support/django/conf/global_settings.py (modified) (1 diff)
- django/branches/multiple-db-support/django/contrib/admin/templatetags/admin_modify.py (modified) (1 diff)
- django/branches/multiple-db-support/django/contrib/admin/views/main.py (modified) (1 diff)
- django/branches/multiple-db-support/django/contrib/auth/decorators.py (modified) (1 diff)
- django/branches/multiple-db-support/django/contrib/auth/handlers/modpython.py (modified) (2 diffs)
- django/branches/multiple-db-support/django/core/context_processors.py (modified) (2 diffs)
- django/branches/multiple-db-support/django/core/handlers/modpython.py (modified) (1 diff)
- django/branches/multiple-db-support/django/core/handlers/wsgi.py (modified) (4 diffs)
- django/branches/multiple-db-support/django/core/management.py (modified) (7 diffs)
- django/branches/multiple-db-support/django/core/serializers/json.py (modified) (1 diff)
- django/branches/multiple-db-support/django/core/servers/basehttp.py (modified) (1 diff)
- django/branches/multiple-db-support/django/core/servers/fastcgi.py (modified) (1 diff)
- django/branches/multiple-db-support/django/core/validators.py (modified) (2 diffs)
- django/branches/multiple-db-support/django/core/xheaders.py (modified) (1 diff)
- django/branches/multiple-db-support/django/db/backends/util.py (modified) (1 diff)
- django/branches/multiple-db-support/django/db/models/fields/generic.py (modified) (1 diff)
- django/branches/multiple-db-support/django/forms/__init__.py (modified) (5 diffs)
- django/branches/multiple-db-support/django/http/__init__.py (modified) (5 diffs)
- django/branches/multiple-db-support/django/middleware/common.py (modified) (1 diff)
- django/branches/multiple-db-support/django/middleware/doc.py (modified) (1 diff)
- django/branches/multiple-db-support/django/template/defaultfilters.py (modified) (1 diff)
- django/branches/multiple-db-support/django/template/defaulttags.py (modified) (3 diffs)
- django/branches/multiple-db-support/django/utils/datastructures.py (modified) (1 diff)
- django/branches/multiple-db-support/django/utils/text.py (modified) (2 diffs)
- django/branches/multiple-db-support/docs/authentication.txt (modified) (3 diffs)
- django/branches/multiple-db-support/docs/contributing.txt (modified) (2 diffs)
- django/branches/multiple-db-support/docs/db-api.txt (modified) (1 diff)
- django/branches/multiple-db-support/docs/django-admin.txt (modified) (2 diffs)
- django/branches/multiple-db-support/docs/forms.txt (modified) (3 diffs)
- django/branches/multiple-db-support/docs/model-api.txt (modified) (1 diff)
- django/branches/multiple-db-support/docs/serialization.txt (modified) (1 diff)
- django/branches/multiple-db-support/docs/settings.txt (modified) (1 diff)
- django/branches/multiple-db-support/docs/templates_python.txt (modified) (3 diffs)
- django/branches/multiple-db-support/README (modified) (1 diff)
- django/branches/multiple-db-support/tests/regressiontests/defaultfilters/tests.py (modified) (1 diff)
- django/branches/multiple-db-support/tests/regressiontests/templates/tests.py (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
django/branches/multiple-db-support/AUTHORS
r3755 r4139 43 43 answer newbie questions, and generally made Django that much better: 44 44 45 adurdin@gmail.com 45 46 akaihola 46 47 Andreas … … 69 70 deric@monowerks.com 70 71 dne@mayonnaise.net 72 Maximillian Dornseif <md@hudora.de> 73 dummy@habmalnefrage.de 71 74 Jeremy Dunck <http://dunck.us/> 72 75 Andy Dustman <farcepest@gmail.com> 73 76 Clint Ecker 77 favo@exoweb.net 74 78 gandalf@owca.info 75 79 Baishampayan Ghose … … 78 82 Espen Grindhaug <http://grindhaug.org/> 79 83 Brant Harris 84 heckj@mac.com 80 85 hipertracker@gmail.com 81 86 Ian Holsman <http://feh.holsman.net/> … … 97 102 Stuart Langridge <http://www.kryogenix.org/> 98 103 Eugene Lazutkin <http://lazutkin.com/blog/> 104 Jeong-Min Lee 99 105 Christopher Lenz <http://www.cmlenz.net/> 100 106 limodou … … 123 129 J. Rademaker 124 130 Michael Radziej <mir@noris.de> 131 ramiro 125 132 Brian Ray <http://brianray.chipy.org/> 126 133 rhettg@gmail.com django/branches/multiple-db-support/django/conf/global_settings.py
r3755 r4139 276 276 COMMENTS_ALLOW_PROFANITIES = False 277 277 278 # The profanities that will trigger a validation error in the 279 # 'hasNoProfanities' validator. All of these should be in lower-case. 280 PROFANITIES_LIST = ['asshat', 'asshead', 'asshole', 'cunt', 'fuck', 'gook', 'nigger', 'shit'] 281 278 282 # The group ID that designates which users are banned. 279 283 # Set to None if you're not using it. django/branches/multiple-db-support/django/contrib/admin/templatetags/admin_modify.py
r3662 r4139 161 161 if relation.field.rel.edit_inline == models.TABULAR: 162 162 bound_related_object_class = TabularBoundRelatedObject 163 elif relation.field.rel.edit_inline == models.STACKED: 164 bound_related_object_class = StackedBoundRelatedObject 163 165 else: 164 bound_related_object_class = StackedBoundRelatedObject166 bound_related_object_class = relation.field.rel.edit_inline 165 167 original = context.get('original', None) 166 168 bound_related_object = relation.bind(context['form'], original, bound_related_object_class) django/branches/multiple-db-support/django/contrib/admin/views/main.py
r3621 r4139 728 728 or_queries = [models.Q(**{construct_search(field_name): bit}) for field_name in self.lookup_opts.admin.search_fields] 729 729 other_qs = QuerySet(self.model) 730 if qs._select_related: 731 other_qs = other_qs.select_related() 730 732 other_qs = other_qs.filter(reduce(operator.or_, or_queries)) 731 733 qs = qs & other_qs django/branches/multiple-db-support/django/contrib/auth/decorators.py
r3502 r4139 27 27 """ 28 28 ) 29 30 def permission_required(perm, login_url=LOGIN_URL): 31 """ 32 Decorator for views that checks if a user has a particular permission 33 enabled, redirectiing to the log-in page if necessary. 34 """ 35 return user_passes_test(lambda u: u.has_perm(perm), login_url=login_url) 36 django/branches/multiple-db-support/django/contrib/auth/handlers/modpython.py
r3012 r4139 23 23 24 24 from django.contrib.auth.models import User 25 from django import db 26 db.reset_queries() 25 27 26 28 # check that the username is valid … … 31 33 kwargs['is_superuser'] = True 32 34 try: 33 user = User.objects.get(**kwargs) 34 except User.DoesNotExist: 35 return apache.HTTP_UNAUTHORIZED 36 37 # check the password and any permission given 38 if user.check_password(req.get_basic_auth_pw()): 39 if permission_name: 40 if user.has_perm(permission_name): 35 try: 36 user = User.objects.get(**kwargs) 37 except User.DoesNotExist: 38 return apache.HTTP_UNAUTHORIZED 39 40 # check the password and any permission given 41 if user.check_password(req.get_basic_auth_pw()): 42 if permission_name: 43 if user.has_perm(permission_name): 44 return apache.OK 45 else: 46 return apache.HTTP_UNAUTHORIZED 47 else: 41 48 return apache.OK 42 else:43 return apache.HTTP_UNAUTHORIZED44 49 else: 45 return apache. OK46 else:47 return apache.HTTP_UNAUTHORIZED50 return apache.HTTP_UNAUTHORIZED 51 finally: 52 db.connection.close() django/branches/multiple-db-support/django/core/context_processors.py
r3113 r4139 52 52 def __init__(self, user, module_name): 53 53 self.user, self.module_name = user, module_name 54 54 55 def __repr__(self): 55 return str(self.user.get_permission_list()) 56 return str(self.user.get_all_permissions()) 57 56 58 def __getitem__(self, perm_name): 57 59 return self.user.has_perm("%s.%s" % (self.module_name, perm_name)) 60 58 61 def __nonzero__(self): 59 62 return self.user.has_module_perms(self.module_name) … … 62 65 def __init__(self, user): 63 66 self.user = user 67 64 68 def __getitem__(self, module_name): 65 69 return PermLookupDict(self.user, module_name) django/branches/multiple-db-support/django/core/handlers/modpython.py
r3427 r4139 156 156 mod_python_req.headers_out.add('Set-Cookie', c.output(header='')) 157 157 mod_python_req.status = http_response.status_code 158 for chunk in http_response.iterator: 159 mod_python_req.write(chunk) 158 try: 159 for chunk in http_response: 160 mod_python_req.write(chunk) 161 finally: 162 http_response.close() 160 163 161 164 def handler(req): django/branches/multiple-db-support/django/core/handlers/wsgi.py
r3427 r4139 5 5 from django import http 6 6 from pprint import pformat 7 from shutil import copyfileobj 8 try: 9 from cStringIO import StringIO 10 except ImportError: 11 from StringIO import StringIO 7 12 8 13 # See http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html … … 50 55 505: 'HTTP VERSION NOT SUPPORTED', 51 56 } 57 58 def safe_copyfileobj(fsrc, fdst, length=16*1024, size=0): 59 """ 60 A version of shutil.copyfileobj that will not read more than 'size' bytes. 61 This makes it safe from clients sending more than CONTENT_LENGTH bytes of 62 data in the body. 63 """ 64 if not size: 65 return copyfileobj(fsrc, fdst, length) 66 while size > 0: 67 buf = fsrc.read(min(length, size)) 68 if not buf: 69 break 70 fdst.write(buf) 71 size -= len(buf) 52 72 53 73 class WSGIRequest(http.HttpRequest): … … 120 140 return self._raw_post_data 121 141 except AttributeError: 122 self._raw_post_data = self.environ['wsgi.input'].read(int(self.environ["CONTENT_LENGTH"])) 142 buf = StringIO() 143 content_length = int(self.environ['CONTENT_LENGTH']) 144 safe_copyfileobj(self.environ['wsgi.input'], buf, size=content_length) 145 self._raw_post_data = buf.getvalue() 146 buf.close() 123 147 return self._raw_post_data 124 148 … … 164 188 response_headers.append(('Set-Cookie', c.output(header=''))) 165 189 start_response(status, response_headers) 166 return response .iterator190 return response django/branches/multiple-db-support/django/core/management.py
r4137 r4139 813 813 f = opts.get_field(fn) 814 814 except models.FieldDoesNotExist: 815 e.add(opts, '"admin.list_filter" refers to %r, which isn\'t a field.' % fn) 815 if not hasattr(cls, fn): 816 e.add(opts, '"admin.list_display_links" refers to %r, which isn\'t an attribute, method or property.' % fn) 816 817 if fn not in opts.admin.list_display: 817 818 e.add(opts, '"admin.list_display_links" refers to %r, which is not defined in "admin.list_display".' % fn) … … 871 872 return len(e.errors) 872 873 873 def validate(outfile=sys.stdout ):874 def validate(outfile=sys.stdout, silent_success=False): 874 875 "Validates all installed models." 875 876 try: 876 877 num_errors = get_validation_errors(outfile) 878 if silent_success and num_errors == 0: 879 return 877 880 outfile.write('%s error%s found.\n' % (num_errors, num_errors != 1 and 's' or '')) 878 881 except ImproperlyConfigured: … … 897 900 sys.exit(1) 898 901 899 def runserver(addr, port, use_reloader=True ):902 def runserver(addr, port, use_reloader=True, admin_media_dir=''): 900 903 "Starts a lightweight Web server for development." 901 904 from django.core.servers.basehttp import run, AdminMediaHandler, WSGIServerException … … 915 918 print "Quit the server with %s." % quit_command 916 919 try: 917 run(addr, int(port), AdminMediaHandler(WSGIHandler())) 920 import django 921 path = admin_media_dir or django.__path__[0] + '/contrib/admin/media' 922 handler = AdminMediaHandler(WSGIHandler(), path) 923 run(addr, int(port), handler) 918 924 except WSGIServerException, e: 919 925 # Use helpful error messages instead of ugly tracebacks. … … 936 942 else: 937 943 inner_run() 938 runserver.args = '[--noreload] [ optional port number, or ipaddr:port]'944 runserver.args = '[--noreload] [--adminmedia=ADMIN_MEDIA_PATH] [optional port number, or ipaddr:port]' 939 945 940 946 def createcachetable(tablename): … … 1122 1128 parser.add_option('--verbosity', action='store', dest='verbosity', default='2', 1123 1129 type='choice', choices=['0', '1', '2'], 1124 help='Verbosity level; 0=minimal output, 1=normal output, 2=all output') 1130 help='Verbosity level; 0=minimal output, 1=normal output, 2=all output'), 1131 parser.add_option('--adminmedia', dest='admin_media_path', default='', help='Lets you manually specify the directory to serve admin media from when running the development server.'), 1125 1132 1126 1133 options, args = parser.parse_args(argv[1:]) … … 1186 1193 except ValueError: 1187 1194 addr, port = '', args[1] 1188 action_mapping[action](addr, port, options.use_reloader )1195 action_mapping[action](addr, port, options.use_reloader, options.admin_media_path) 1189 1196 elif action == 'runfcgi': 1190 1197 action_mapping[action](args[1:]) 1191 1198 else: 1192 1199 from django.db import models 1200 validate(silent_success=True) 1193 1201 try: 1194 1202 mod_list = [models.get_app(app_label) for app_label in args[1:]] django/branches/multiple-db-support/django/core/serializers/json.py
r3712 r4139 17 17 """ 18 18 def end_serialization(self): 19 simplejson.dump(self.objects, self.stream, cls=DateTimeAwareJSONEncoder )19 simplejson.dump(self.objects, self.stream, cls=DateTimeAwareJSONEncoder, **self.options) 20 20 21 21 def getvalue(self): django/branches/multiple-db-support/django/core/servers/basehttp.py
r3581 r4139 595 595 security and is not super efficient. 596 596 """ 597 def __init__(self, application ):597 def __init__(self, application, media_dir = None): 598 598 from django.conf import settings 599 import django600 599 self.application = application 601 self.media_dir = django.__path__[0] + '/contrib/admin/media' 600 if not media_dir: 601 import django 602 self.media_dir = django.__path__[0] + '/contrib/admin/media' 603 else: 604 self.media_dir = media_dir 602 605 self.media_url = settings.ADMIN_MEDIA_PREFIX 603 606 django/branches/multiple-db-support/django/core/servers/fastcgi.py
r4138 r4139 75 75 return False 76 76 77 def runfastcgi(argset , **kwargs):77 def runfastcgi(argset=[], **kwargs): 78 78 options = FASTCGI_OPTIONS.copy() 79 79 options.update(kwargs) django/branches/multiple-db-support/django/core/validators.py
r3648 r4139 228 228 Watch your mouth! The words "f--k" and "s--t" are not allowed here. 229 229 """ 230 bad_words = ['asshat', 'asshead', 'asshole', 'cunt', 'fuck', 'gook', 'nigger', 'shit'] # all in lower case231 230 field_data = field_data.lower() # normalize 232 words_seen = [w for w in bad_wordsif field_data.find(w) > -1]231 words_seen = [w for w in settings.PROFANITIES_LIST if field_data.find(w) > -1] 233 232 if words_seen: 234 233 from django.utils.text import get_text_list … … 353 352 except ValueError: 354 353 raise ValidationError, gettext("Please enter a valid decimal number.") 355 if len(data) > (self.max_digits + 1): 354 # Negative floats require more space to input. 355 max_allowed_length = data.startswith('-') and (self.max_digits + 2) or (self.max_digits + 1) 356 if len(data) > max_allowed_length: 356 357 raise ValidationError, ngettext("Please enter a valid decimal number with at most %s total digit.", 357 358 "Please enter a valid decimal number with at most %s total digits.", self.max_digits) % self.max_digits 358 if (not '.' in data and len(data) > ( self.max_digits- self.decimal_places)) or ('.' in data and len(data) > (self.max_digits - (self.decimal_places - len(data.split('.')[1])) + 1)):359 if (not '.' in data and len(data) > (max_allowed_length - self.decimal_places)) or ('.' in data and len(data) > (self.max_digits - (self.decimal_places - len(data.split('.')[1])) + 1)): 359 360 raise ValidationError, ngettext( "Please enter a valid decimal number with a whole part of at most %s digit.", 360 361 "Please enter a valid decimal number with a whole part of at most %s digits.", str(self.max_digits-self.decimal_places)) % str(self.max_digits-self.decimal_places) django/branches/multiple-db-support/django/core/xheaders.py
r2809 r4139 14 14 Adds the "X-Object-Type" and "X-Object-Id" headers to the given 15 15 HttpResponse according to the given model and object_id -- but only if the 16 given HttpRequest object has an IP address within the INTERNAL_IPS setting. 16 given HttpRequest object has an IP address within the INTERNAL_IPS setting 17 or if the request is from a logged in staff member. 17 18 """ 18 19 from django.conf import settings 19 if request.META.get('REMOTE_ADDR') in settings.INTERNAL_IPS :20 if request.META.get('REMOTE_ADDR') in settings.INTERNAL_IPS or (request.user.is_authenticated() and request.user.is_staff): 20 21 response['X-Object-Type'] = "%s.%s" % (model._meta.app_label, model._meta.object_name.lower()) 21 22 response['X-Object-Id'] = str(object_id) django/branches/multiple-db-support/django/db/backends/util.py
r3712 r4139 111 111 "Returns a certain number of rows from a cursor as a dict" 112 112 desc = cursor.description 113 return [_dict_helper(desc, row) for row in cursor.fetchmany(number)] 113 for row in cursor.fetchmany(number): 114 yield _dict_helper(desc, row) 114 115 115 116 def dictfetchall(cursor): 116 117 "Returns all rows from a cursor as a dict" 117 118 desc = cursor.description 118 return [_dict_helper(desc, row) for row in cursor.fetchall()] 119 for row in cursor.fetchall(): 120 yield _dict_helper(desc, row) django/branches/multiple-db-support/django/db/models/fields/generic.py
r3134 r4139 118 118 119 119 def m2m_reverse_name(self): 120 return self. model._meta.pk.attname120 return self.object_id_field_name 121 121 122 122 def contribute_to_class(self, cls, name): django/branches/multiple-db-support/django/forms/__init__.py
r3502 r4139 435 435 436 436 class CheckboxField(FormField): 437 def __init__(self, field_name, checked_by_default=False, validator_list=None ):437 def __init__(self, field_name, checked_by_default=False, validator_list=None, is_required=False): 438 438 if validator_list is None: validator_list = [] 439 439 self.field_name = field_name 440 440 self.checked_by_default = checked_by_default 441 self.is_required = False # because the validator looks for these441 self.is_required = is_required 442 442 self.validator_list = validator_list[:] 443 443 … … 640 640 field_name = '%s%s' % (self.field_name, value) 641 641 output.append('<li><input type="checkbox" id="%s" class="v%s" name="%s"%s /> <label for="%s">%s</label></li>' % \ 642 (self.get_id() + value, self.__class__.__name__, field_name, checked_html,643 self.get_id() + value, choice))642 (self.get_id() + escape(value), self.__class__.__name__, field_name, checked_html, 643 self.get_id() + escape(value), choice)) 644 644 output.append('</ul>') 645 645 return '\n'.join(output) … … 744 744 self.max_digits, self.decimal_places = max_digits, decimal_places 745 745 validator_list = [self.isValidFloat] + validator_list 746 TextField.__init__(self, field_name, max_digits+ 1, max_digits+1, is_required, validator_list)746 TextField.__init__(self, field_name, max_digits+2, max_digits+2, is_required, validator_list) 747 747 748 748 def isValidFloat(self, field_data, all_data): … … 953 953 954 954 def html2python(data): 955 if data: 956 return data.upper() # Should always be stored in upper case 957 else: 958 return None 955 return data.upper() # Should always be stored in upper case 959 956 html2python = staticmethod(html2python) 960 957 … … 973 970 raise validators.CriticalValidationError, e.messages 974 971 972 def render(self, data): 973 if data is None: 974 data = '' 975 elif isinstance(data, (list, tuple)): 976 data = ','.join(data) 977 return super(CommaSeparatedIntegerField, self).render(data) 978 975 979 class RawIdAdminField(CommaSeparatedIntegerField): 976 980 def html2python(data): 977 return data.split(',') 981 if data: 982 return data.split(',') 983 else: 984 return [] 978 985 html2python = staticmethod(html2python) 979 986 django/branches/multiple-db-support/django/http/__init__.py
r3581 r4139 162 162 mimetype = "%s; charset=%s" % (settings.DEFAULT_CONTENT_TYPE, settings.DEFAULT_CHARSET) 163 163 if hasattr(content, '__iter__'): 164 self._ iterator = content164 self._container = content 165 165 self._is_string = False 166 166 else: 167 self._ iterator = [content]167 self._container = [content] 168 168 self._is_string = True 169 169 self.headers = {'Content-Type': mimetype} … … 214 214 215 215 def _get_content(self): 216 content = ''.join(self._ iterator)216 content = ''.join(self._container) 217 217 if isinstance(content, unicode): 218 218 content = content.encode(self._charset) … … 220 220 221 221 def _set_content(self, value): 222 self._ iterator = [value]222 self._container = [value] 223 223 self._is_string = True 224 224 225 225 content = property(_get_content, _set_content) 226 226 227 def _get_iterator(self): 228 "Output iterator. Converts data into client charset if necessary." 229 for chunk in self._iterator: 230 if isinstance(chunk, unicode): 231 chunk = chunk.encode(self._charset) 232 yield chunk 233 234 iterator = property(_get_iterator) 227 def __iter__(self): 228 self._iterator = self._container.__iter__() 229 return self 230 231 def next(self): 232 chunk = self._iterator.next() 233 if isinstance(chunk, unicode): 234 chunk = chunk.encode(self._charset) 235 return chunk 236 237 def close(self): 238 if hasattr(self._container, 'close'): 239 self._container.close() 235 240 236 241 # The remaining methods partially implement the file-like object interface. … … 239 244 if not self._is_string: 240 245 raise Exception, "This %s instance is not writable" % self.__class__ 241 self._ iterator.append(content)246 self._container.append(content) 242 247 243 248 def flush(self): … … 247 252 if not self._is_string: 248 253 raise Exception, "This %s instance cannot tell its position" % self.__class__ 249 return sum([len(chunk) for chunk in self._ iterator])254 return sum([len(chunk) for chunk in self._container]) 250 255 251 256 class HttpResponseRedirect(HttpResponse): django/branches/multiple-db-support/django/middleware/common.py
r3427 r4139 65 65 path = request.get_full_path() 66 66 if referer and not _is_ignorable_404(path) and (is_internal or '?' not in referer): 67 ua = request.META.get('HTTP_USER_AGENT','<none>') 67 68 mail_managers("Broken %slink on %s" % ((is_internal and 'INTERNAL ' or ''), domain), 68 "Referrer: %s\nRequested URL: %s\n " % (referer, request.get_full_path()))69 "Referrer: %s\nRequested URL: %s\nUser Agent: %s\n" % (referer, request.get_full_path(), ua)) 69 70 return response 70 71 django/branches/multiple-db-support/django/middleware/doc.py
r3171 r4139 8 8 def process_view(self, request, view_func, view_args, view_kwargs): 9 9 """ 10 If the request method is HEAD and the IP is internal, quickly return 11 with an x-header indicating the view function. This is used by the 12 documentation module to lookup the view function for an arbitrary page. 10 If the request method is HEAD and either the IP is internal or the 11 user is a logged-in staff member, quickly return with an x-header 12 indicating the view function. This is used by the documentation module 13 to lookup the view function for an arbitrary page. 13 14 """ 14 if request.method == 'HEAD' and request.META.get('REMOTE_ADDR') in settings.INTERNAL_IPS:15 if request.method == 'HEAD' and (request.META.get('REMOTE_ADDR') in settings.INTERNAL_IPS or (request.user.is_authenticated() and request.user.is_staff)): 15 16 response = http.HttpResponse() 16 17 response['X-View'] = "%s.%s" % (view_func.__module__, view_func.__name__) django/branches/multiple-db-support/django/template/defaultfilters.py
r3581 r4139 16 16 def addslashes(value): 17 17 "Adds slashes - useful for passing strings to JavaScript, for example." 18 return value.replace(' "', '\\"').replace("'", "\\'")18 return value.replace('\\', '\\\\').replace('"', '\\"').replace("'", "\\'") 19 19 20 20 def capfirst(value): django/branches/multiple-db-support/django/template/defaulttags.py
r3739 r4139 14 14 15 15 class CycleNode(Node): 16 def __init__(self, cyclevars ):16 def __init__(self, cyclevars, variable_name=None): 17 17 self.cyclevars = cyclevars 18 18 self.cyclevars_len = len(cyclevars) 19 19 self.counter = -1 20 self.variable_name = variable_name 20 21 21 22 def render(self, context): 22 23 self.counter += 1 23 return self.cyclevars[self.counter % self.cyclevars_len] 24 value = self.cyclevars[self.counter % self.cyclevars_len] 25 if self.variable_name: 26 context[self.variable_name] = value 27 return value 24 28 25 29 class DebugNode(Node): … … 126 130 127 131 def render(self, context): 132 if context.has_key('forloop') and context['forloop']['first']: 133 self._last_seen = None 128 134 content = self.nodelist.render(context) 129 135 if content != self._last_seen: … … 386 392 cyclevars = [v for v in args[1].split(",") if v] # split and kill blanks 387 393 name = args[3] 388 node = CycleNode(cyclevars )394 node = CycleNode(cyclevars, name) 389 395 390 396 if not hasattr(parser, '_namedCycleNodes'): django/branches/multiple-db-support/django/utils/datastructures.py
r3712 r4139 14 14 pass 15 15 raise KeyError 16 17 def __contains__(self, key): 18 return self.has_key(key) 16 19 17 20 def get(self, key, default): django/branches/multiple-db-support/django/utils/text.py
r3111 r4139 95 95 96 96 ustring_re = re.compile(u"([\u0080-\uffff])") 97 def javascript_quote(s): 97 98 def javascript_quote(s, quote_double_quotes=False): 98 99 99 100 def fix(match): … … 105 106 raise TypeError, s 106 107 s = s.replace('\\', '\\\\') 108 s = s.replace('\r', '\\r') 107 109 s = s.replace('\n', '\\n') 108 110 s = s.replace('\t', '\\t') 109 111 s = s.replace("'", "\\'") 112 if quote_double_quotes: 113 s = s.replace('"', '"') 110 114 return str(ustring_re.sub(fix, s)) 111 115 django/branches/multiple-db-support/docs/authentication.txt
r3755 r4139 457 457 my_view = user_passes_test(lambda u: u.has_perm('polls.can_vote'))(my_view) 458 458 459 We are using this particular test as a relatively simple example, however be 460 aware that if you just want to test if a permission is available to a user, 461 you can use the ``permission_required()`` decorator described below. 462 459 463 Here's the same thing, using Python 2.4's decorator syntax:: 460 464 … … 488 492 def my_view(request): 489 493 # ... 494 495 The permission_required decorator 496 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 497 498 Since checking whether a user has a particular permission available to them is a 499 relatively common operation, Django provides a shortcut for that particular 500 case: the ``permission_required()`` decorator. Using this decorator, the 501 earlier example can be written as:: 502 503 from django.contrib.auth.decorators import permission_required 504 505 def my_view(request): 506 # ... 507 508 my_view = permission_required('polls.can_vote')(my_view) 509 510 Note that ``permission_required()`` also takes an optional ``login_url`` 511 parameter. 490 512 491 513 Limiting access to generic views … … 678 700 ``"The poll Foo was created successfully."`` is a message. 679 701 680 The API is simple: :702 The API is simple: 681 703 682 704 * To create a new message, use django/branches/multiple-db-support/docs/contributing.txt
r3712 r4139 248 248 The tests cover: 249 249 250 * Models and the database API (``tests/testapp/models``). 251 * The cache system (``tests/otherthests/cache.py``). 252 * The ``django.utils.dateformat`` module (``tests/othertests/dateformat.py``). 253 * Database typecasts (``tests/othertests/db_typecasts.py``). 254 * The template system (``tests/othertests/templates.py`` and 255 ``tests/othertests/defaultfilters.py``). 256 * ``QueryDict`` objects (``tests/othertests/httpwrappers.py``). 257 * Markup template tags (``tests/othertests/markup.py``). 258 * The ``django.utils.timesince`` module (``tests/othertests/timesince.py``). 250 * Models and the database API (``tests/modeltests/``). 251 * The cache system (``tests/regressiontests/cache.py``). 252 * The ``django.utils.dateformat`` module (``tests/regressiontests/dateformat/``). 253 * Database typecasts (``tests/regressiontests/db_typecasts/``). 254 * The template system (``tests/regressiontests/templates/`` and 255 ``tests/regressiontests/defaultfilters/``). 256 * ``QueryDict`` objects (``tests/regressiontests/httpwrappers/``). 257 * Markup template tags (``tests/regressiontests/markup/``). 259 258 260 259 We appreciate any and all contributions to the test suite! 260 261 The Django tests all use the testing infrastructure that ships with Django for 262 testing applications. See `Testing Django Applications`_ for an explanation of 263 how to write new tests. 264 265 .. _Testing Django Applications: http://www.djangoproject.com/documentation/testing/ 261 266 262 267 Running the unit tests … … 269 274 Yes, the unit tests need a settings module, but only for database connection 270 275 info -- the ``DATABASE_ENGINE``, ``DATABASE_USER`` and ``DATABASE_PASSWORD``. 271 272 The unit tests will not touch your database; they create a new database, called 273 ``django_test_db``, which is deleted when the tests are finished. This means 274 your user account needs permission to execute ``CREATE DATABASE``. 276 You will also need a ``ROOT_URLCONF`` setting (it's value is ignored; it just 277 needs to be present) and a ``SITE_ID`` setting (any integer value will do) in 278 order for all the tests to pass. 279 280 The unit tests will not touch your existing databases; they create a new 281 database, called ``django_test_db``, which is deleted when the tests are 282 finished. This means your user account needs permission to execute ``CREATE 283 DATABASE``. 275 284 276 285 Requesting features django/branches/multiple-db-support/docs/db-api.txt
