Django

Code

Changeset 4139

Show
Ignore:
Timestamp:
11/29/06 14:02:43 (2 years ago)
Author:
jpellerin
Message:

[multi-db] Merge trunk to [3812]. Some tests still failing.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/branches/multiple-db-support/AUTHORS

    r3755 r4139  
    4343answer newbie questions, and generally made Django that much better: 
    4444 
     45    adurdin@gmail.com 
    4546    akaihola 
    4647    Andreas 
     
    6970    deric@monowerks.com 
    7071    dne@mayonnaise.net 
     72    Maximillian Dornseif <md@hudora.de> 
     73    dummy@habmalnefrage.de 
    7174    Jeremy Dunck <http://dunck.us/> 
    7275    Andy Dustman <farcepest@gmail.com> 
    7376    Clint Ecker 
     77    favo@exoweb.net 
    7478    gandalf@owca.info 
    7579    Baishampayan Ghose 
     
    7882    Espen Grindhaug <http://grindhaug.org/> 
    7983    Brant Harris 
     84    heckj@mac.com 
    8085    hipertracker@gmail.com 
    8186    Ian Holsman <http://feh.holsman.net/> 
     
    97102    Stuart Langridge <http://www.kryogenix.org/> 
    98103    Eugene Lazutkin <http://lazutkin.com/blog/> 
     104    Jeong-Min Lee 
    99105    Christopher Lenz <http://www.cmlenz.net/> 
    100106    limodou 
     
    123129    J. Rademaker 
    124130    Michael Radziej <mir@noris.de> 
     131    ramiro 
    125132    Brian Ray <http://brianray.chipy.org/> 
    126133    rhettg@gmail.com 
  • django/branches/multiple-db-support/django/conf/global_settings.py

    r3755 r4139  
    276276COMMENTS_ALLOW_PROFANITIES = False 
    277277 
     278# The profanities that will trigger a validation error in the 
     279# 'hasNoProfanities' validator. All of these should be in lower-case. 
     280PROFANITIES_LIST = ['asshat', 'asshead', 'asshole', 'cunt', 'fuck', 'gook', 'nigger', 'shit'] 
     281 
    278282# The group ID that designates which users are banned. 
    279283# Set to None if you're not using it. 
  • django/branches/multiple-db-support/django/contrib/admin/templatetags/admin_modify.py

    r3662 r4139  
    161161        if relation.field.rel.edit_inline == models.TABULAR: 
    162162            bound_related_object_class = TabularBoundRelatedObject 
     163        elif relation.field.rel.edit_inline == models.STACKED: 
     164            bound_related_object_class = StackedBoundRelatedObject 
    163165        else: 
    164             bound_related_object_class = StackedBoundRelatedObject 
     166            bound_related_object_class = relation.field.rel.edit_inline 
    165167        original = context.get('original', None) 
    166168        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  
    728728                or_queries = [models.Q(**{construct_search(field_name): bit}) for field_name in self.lookup_opts.admin.search_fields] 
    729729                other_qs = QuerySet(self.model) 
     730                if qs._select_related: 
     731                    other_qs = other_qs.select_related() 
    730732                other_qs = other_qs.filter(reduce(operator.or_, or_queries)) 
    731733                qs = qs & other_qs 
  • django/branches/multiple-db-support/django/contrib/auth/decorators.py

    r3502 r4139  
    2727    """ 
    2828    ) 
     29 
     30def 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  
    2323 
    2424    from django.contrib.auth.models import User 
     25    from django import db 
     26    db.reset_queries() 
    2527 
    2628    # check that the username is valid 
     
    3133        kwargs['is_superuser'] = True 
    3234    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: 
    4148                return apache.OK 
    42             else: 
    43                 return apache.HTTP_UNAUTHORIZED 
    4449        else: 
    45             return apache.OK 
    46     else
    47         return apache.HTTP_UNAUTHORIZED 
     50            return apache.HTTP_UNAUTHORIZED 
     51    finally
     52        db.connection.close() 
  • django/branches/multiple-db-support/django/core/context_processors.py

    r3113 r4139  
    5252    def __init__(self, user, module_name): 
    5353        self.user, self.module_name = user, module_name 
     54 
    5455    def __repr__(self): 
    55         return str(self.user.get_permission_list()) 
     56        return str(self.user.get_all_permissions()) 
     57 
    5658    def __getitem__(self, perm_name): 
    5759        return self.user.has_perm("%s.%s" % (self.module_name, perm_name)) 
     60 
    5861    def __nonzero__(self): 
    5962        return self.user.has_module_perms(self.module_name) 
     
    6265    def __init__(self, user): 
    6366        self.user = user 
     67 
    6468    def __getitem__(self, module_name): 
    6569        return PermLookupDict(self.user, module_name) 
  • django/branches/multiple-db-support/django/core/handlers/modpython.py

    r3427 r4139  
    156156        mod_python_req.headers_out.add('Set-Cookie', c.output(header='')) 
    157157    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() 
    160163 
    161164def handler(req): 
  • django/branches/multiple-db-support/django/core/handlers/wsgi.py

    r3427 r4139  
    55from django import http 
    66from pprint import pformat 
     7from shutil import copyfileobj 
     8try: 
     9    from cStringIO import StringIO 
     10except ImportError: 
     11    from StringIO import StringIO 
    712 
    813# See http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html 
     
    5055    505: 'HTTP VERSION NOT SUPPORTED', 
    5156} 
     57 
     58def 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) 
    5272 
    5373class WSGIRequest(http.HttpRequest): 
     
    120140            return self._raw_post_data 
    121141        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() 
    123147            return self._raw_post_data 
    124148 
     
    164188            response_headers.append(('Set-Cookie', c.output(header=''))) 
    165189        start_response(status, response_headers) 
    166         return response.iterator 
     190        return response 
  • django/branches/multiple-db-support/django/core/management.py

    r4137 r4139  
    813813                            f = opts.get_field(fn) 
    814814                        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) 
    816817                        if fn not in opts.admin.list_display: 
    817818                            e.add(opts, '"admin.list_display_links" refers to %r, which is not defined in "admin.list_display".' % fn) 
     
    871872    return len(e.errors) 
    872873 
    873 def validate(outfile=sys.stdout): 
     874def validate(outfile=sys.stdout, silent_success=False): 
    874875    "Validates all installed models." 
    875876    try: 
    876877        num_errors = get_validation_errors(outfile) 
     878        if silent_success and num_errors == 0: 
     879            return 
    877880        outfile.write('%s error%s found.\n' % (num_errors, num_errors != 1 and 's' or '')) 
    878881    except ImproperlyConfigured: 
     
    897900        sys.exit(1) 
    898901 
    899 def runserver(addr, port, use_reloader=True): 
     902def runserver(addr, port, use_reloader=True, admin_media_dir=''): 
    900903    "Starts a lightweight Web server for development." 
    901904    from django.core.servers.basehttp import run, AdminMediaHandler, WSGIServerException 
     
    915918        print "Quit the server with %s." % quit_command 
    916919        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) 
    918924        except WSGIServerException, e: 
    919925            # Use helpful error messages instead of ugly tracebacks. 
     
    936942    else: 
    937943        inner_run() 
    938 runserver.args = '[--noreload] [optional port number, or ipaddr:port]' 
     944runserver.args = '[--noreload] [--adminmedia=ADMIN_MEDIA_PATH] [optional port number, or ipaddr:port]' 
    939945 
    940946def createcachetable(tablename): 
     
    11221128    parser.add_option('--verbosity', action='store', dest='verbosity', default='2', 
    11231129        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.'), 
    11251132 
    11261133    options, args = parser.parse_args(argv[1:]) 
     
    11861193            except ValueError: 
    11871194                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
    11891196    elif action == 'runfcgi': 
    11901197        action_mapping[action](args[1:]) 
    11911198    else: 
    11921199        from django.db import models 
     1200        validate(silent_success=True) 
    11931201        try: 
    11941202            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  
    1717    """ 
    1818    def end_serialization(self): 
    19         simplejson.dump(self.objects, self.stream, cls=DateTimeAwareJSONEncoder
     19        simplejson.dump(self.objects, self.stream, cls=DateTimeAwareJSONEncoder, **self.options
    2020         
    2121    def getvalue(self): 
  • django/branches/multiple-db-support/django/core/servers/basehttp.py

    r3581 r4139  
    595595    security and is not super efficient. 
    596596    """ 
    597     def __init__(self, application): 
     597    def __init__(self, application, media_dir = None): 
    598598        from django.conf import settings 
    599         import django 
    600599        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 
    602605        self.media_url = settings.ADMIN_MEDIA_PREFIX 
    603606 
  • django/branches/multiple-db-support/django/core/servers/fastcgi.py

    r4138 r4139  
    7575    return False 
    7676 
    77 def runfastcgi(argset, **kwargs): 
     77def runfastcgi(argset=[], **kwargs): 
    7878    options = FASTCGI_OPTIONS.copy() 
    7979    options.update(kwargs) 
  • django/branches/multiple-db-support/django/core/validators.py

    r3648 r4139  
    228228        Watch your mouth! The words "f--k" and "s--t" are not allowed here. 
    229229    """ 
    230     bad_words = ['asshat', 'asshead', 'asshole', 'cunt', 'fuck', 'gook', 'nigger', 'shit'] # all in lower case 
    231230    field_data = field_data.lower() # normalize 
    232     words_seen = [w for w in bad_words if field_data.find(w) > -1] 
     231    words_seen = [w for w in settings.PROFANITIES_LIST if field_data.find(w) > -1] 
    233232    if words_seen: 
    234233        from django.utils.text import get_text_list 
     
    353352        except ValueError: 
    354353            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: 
    356357            raise ValidationError, ngettext("Please enter a valid decimal number with at most %s total digit.", 
    357358                "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)): 
    359360            raise ValidationError, ngettext( "Please enter a valid decimal number with a whole part of at most %s digit.", 
    360361                "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  
    1414    Adds the "X-Object-Type" and "X-Object-Id" headers to the given 
    1515    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. 
    1718    """ 
    1819    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)
    2021        response['X-Object-Type'] = "%s.%s" % (model._meta.app_label, model._meta.object_name.lower()) 
    2122        response['X-Object-Id'] = str(object_id) 
  • django/branches/multiple-db-support/django/db/backends/util.py

    r3712 r4139  
    111111    "Returns a certain number of rows from a cursor as a dict" 
    112112    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) 
    114115 
    115116def dictfetchall(cursor): 
    116117    "Returns all rows from a cursor as a dict" 
    117118    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  
    118118         
    119119    def m2m_reverse_name(self): 
    120         return self.model._meta.pk.attname 
     120        return self.object_id_field_name 
    121121 
    122122    def contribute_to_class(self, cls, name): 
  • django/branches/multiple-db-support/django/forms/__init__.py

    r3502 r4139  
    435435 
    436436class 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): 
    438438        if validator_list is None: validator_list = [] 
    439439        self.field_name = field_name 
    440440        self.checked_by_default = checked_by_default 
    441         self.is_required = False # because the validator looks for these 
     441        self.is_required = is_required 
    442442        self.validator_list = validator_list[:] 
    443443 
     
    640640            field_name = '%s%s' % (self.field_name, value) 
    641641            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)) 
    644644        output.append('</ul>') 
    645645        return '\n'.join(output) 
     
    744744        self.max_digits, self.decimal_places = max_digits, decimal_places 
    745745        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) 
    747747 
    748748    def isValidFloat(self, field_data, all_data): 
     
    953953 
    954954    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 
    959956    html2python = staticmethod(html2python) 
    960957 
     
    973970            raise validators.CriticalValidationError, e.messages 
    974971 
     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 
    975979class RawIdAdminField(CommaSeparatedIntegerField): 
    976980    def html2python(data): 
    977         return data.split(',') 
     981        if data: 
     982            return data.split(',') 
     983        else: 
     984            return [] 
    978985    html2python = staticmethod(html2python) 
    979986 
  • django/branches/multiple-db-support/django/http/__init__.py

    r3581 r4139  
    162162            mimetype = "%s; charset=%s" % (settings.DEFAULT_CONTENT_TYPE, settings.DEFAULT_CHARSET) 
    163163        if hasattr(content, '__iter__'): 
    164             self._iterator = content 
     164            self._container = content 
    165165            self._is_string = False 
    166166        else: 
    167             self._iterator = [content] 
     167            self._container = [content] 
    168168            self._is_string = True 
    169169        self.headers = {'Content-Type': mimetype} 
     
    214214 
    215215    def _get_content(self): 
    216         content = ''.join(self._iterator) 
     216        content = ''.join(self._container) 
    217217        if isinstance(content, unicode): 
    218218            content = content.encode(self._charset) 
     
    220220 
    221221    def _set_content(self, value): 
    222         self._iterator = [value] 
     222        self._container = [value] 
    223223        self._is_string = True 
    224224 
    225225    content = property(_get_content, _set_content) 
    226226 
    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() 
    235240 
    236241    # The remaining methods partially implement the file-like object interface. 
     
    239244        if not self._is_string: 
    240245            raise Exception, "This %s instance is not writable" % self.__class__ 
    241         self._iterator.append(content) 
     246        self._container.append(content) 
    242247 
    243248    def flush(self): 
     
    247252        if not self._is_string: 
    248253            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]) 
    250255 
    251256class HttpResponseRedirect(HttpResponse): 
  • django/branches/multiple-db-support/django/middleware/common.py

    r3427 r4139  
    6565                path = request.get_full_path() 
    6666                if referer and not _is_ignorable_404(path) and (is_internal or '?' not in referer): 
     67                    ua = request.META.get('HTTP_USER_AGENT','<none>') 
    6768                    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)) 
    6970                return response 
    7071 
  • django/branches/multiple-db-support/django/middleware/doc.py

    r3171 r4139  
    88    def process_view(self, request, view_func, view_args, view_kwargs): 
    99        """ 
    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. 
    1314        """ 
    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))
    1516            response = http.HttpResponse() 
    1617            response['X-View'] = "%s.%s" % (view_func.__module__, view_func.__name__) 
  • django/branches/multiple-db-support/django/template/defaultfilters.py

    r3581 r4139  
    1616def addslashes(value): 
    1717    "Adds slashes - useful for passing strings to JavaScript, for example." 
    18     return value.replace('"', '\\"').replace("'", "\\'") 
     18    return value.replace('\\', '\\\\').replace('"', '\\"').replace("'", "\\'") 
    1919 
    2020def capfirst(value): 
  • django/branches/multiple-db-support/django/template/defaulttags.py

    r3739 r4139  
    1414 
    1515class CycleNode(Node): 
    16     def __init__(self, cyclevars): 
     16    def __init__(self, cyclevars, variable_name=None): 
    1717        self.cyclevars = cyclevars 
    1818        self.cyclevars_len = len(cyclevars) 
    1919        self.counter = -1 
     20        self.variable_name = variable_name 
    2021 
    2122    def render(self, context): 
    2223        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 
    2428 
    2529class DebugNode(Node): 
     
    126130 
    127131    def render(self, context): 
     132        if context.has_key('forloop') and context['forloop']['first']: 
     133            self._last_seen = None 
    128134        content = self.nodelist.render(context) 
    129135        if content != self._last_seen: 
     
    386392        cyclevars = [v for v in args[1].split(",") if v]    # split and kill blanks 
    387393        name = args[3] 
    388         node = CycleNode(cyclevars
     394        node = CycleNode(cyclevars, name
    389395 
    390396        if not hasattr(parser, '_namedCycleNodes'): 
  • django/branches/multiple-db-support/django/utils/datastructures.py

    r3712 r4139  
    1414                pass 
    1515        raise KeyError 
     16 
     17    def __contains__(self, key): 
     18        return self.has_key(key) 
    1619 
    1720    def get(self, key, default): 
  • django/branches/multiple-db-support/django/utils/text.py

    r3111 r4139  
    9595 
    9696ustring_re = re.compile(u"([\u0080-\uffff])") 
    97 def javascript_quote(s): 
     97 
     98def javascript_quote(s, quote_double_quotes=False): 
    9899 
    99100    def fix(match): 
     
    105106        raise TypeError, s 
    106107    s = s.replace('\\', '\\\\') 
     108    s = s.replace('\r', '\\r') 
    107109    s = s.replace('\n', '\\n') 
    108110    s = s.replace('\t', '\\t') 
    109111    s = s.replace("'", "\\'") 
     112    if quote_double_quotes: 
     113        s = s.replace('"', '&quot;') 
    110114    return str(ustring_re.sub(fix, s)) 
    111115 
  • django/branches/multiple-db-support/docs/authentication.txt

    r3755 r4139  
    457457    my_view = user_passes_test(lambda u: u.has_perm('polls.can_vote'))(my_view) 
    458458 
     459We are using this particular test as a relatively simple example, however be 
     460aware that if you just want to test if a permission is available to a user, 
     461you can use the ``permission_required()`` decorator described below. 
     462 
    459463Here's the same thing, using Python 2.4's decorator syntax:: 
    460464 
     
    488492    def my_view(request): 
    489493        # ... 
     494 
     495The permission_required decorator 
     496~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
     497 
     498Since checking whether a user has a particular permission available to them is a 
     499relatively common operation, Django provides a shortcut for that particular 
     500case: the ``permission_required()`` decorator. Using this decorator, the 
     501earlier 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 
     510Note that ``permission_required()`` also takes an optional ``login_url`` 
     511parameter. 
    490512 
    491513Limiting access to generic views 
     
    678700``"The poll Foo was created successfully."`` is a message. 
    679701 
    680 The API is simple:: 
     702The API is simple: 
    681703 
    682704    * To create a new message, use 
  • django/branches/multiple-db-support/docs/contributing.txt

    r3712 r4139  
    248248The tests cover: 
    249249 
    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/``). 
    259258 
    260259We appreciate any and all contributions to the test suite! 
     260 
     261The Django tests all use the testing infrastructure that ships with Django for 
     262testing applications. See `Testing Django Applications`_ for an explanation of 
     263how to write new tests. 
     264 
     265.. _Testing Django Applications: http://www.djangoproject.com/documentation/testing/ 
    261266 
    262267Running the unit tests 
     
    269274Yes, the unit tests need a settings module, but only for database connection 
    270275info -- 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``. 
     276You will also need a ``ROOT_URLCONF`` setting (it's value is ignored; it just 
     277needs to be present) and a ``SITE_ID`` setting (any integer value will do) in 
     278order for all the tests to pass. 
     279 
     280The unit tests will not touch your existing databases; they create a new 
     281database, called ``django_test_db``, which is deleted when the tests are 
     282finished. This means your user account needs permission to execute ``CREATE 
     283DATABASE``. 
    275284 
    276285Requesting features 
  • django/branches/multiple-db-support/docs/db-api.txt