Django

Code

Changeset 7124

Show
Ignore:
Timestamp:
02/16/08 00:57:52 (8 months ago)
Author:
mtredinnick
Message:

queryset-refactor: Merged from trunk up to [7122].

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/branches/queryset-refactor/AUTHORS

    r7086 r7124  
    169169    Jason Huggins <http://www.jrandolph.com/blog/> 
    170170    Hyun Mi Ae 
     171    Ibon <ibonso@gmail.com> 
    171172    Tom Insam 
    172173    Baurzhan Ismagulov <ibr@radix50.net> 
  • django/branches/queryset-refactor/django/conf/global_settings.py

    r7099 r7124  
    4949    ('es', gettext_noop('Spanish')), 
    5050    ('es-ar', gettext_noop('Argentinean Spanish')), 
     51    ('eu', gettext_noop('Basque')), 
    5152    ('fa', gettext_noop('Persian')), 
    5253    ('fi', gettext_noop('Finnish')), 
  • django/branches/queryset-refactor/django/core/management/commands/sqlall.py

    r5898 r7124  
    22 
    33class Command(AppCommand): 
    4     help = "Prints the CREATE TABLE, initial-data and CREATE INDEX SQL statements for the given model module name(s)." 
     4    help = "Prints the CREATE TABLE, custom SQL and CREATE INDEX SQL statements for the given model module name(s)." 
    55 
    66    output_transaction = True 
  • django/branches/queryset-refactor/django/db/models/base.py

    r7099 r7124  
    4242        # Build complete list of parents 
    4343        for base in parents: 
    44             if base is not Model: 
     44            # Things without _meta aren't functional models, so they're 
     45            # uninteresting parents. 
     46            if hasattr(base, '_meta'): 
    4547                new_class._meta.parents.append(base) 
    4648                new_class._meta.parents.extend(base._meta.parents) 
     
    140142        # overrides it. It should be one or the other; don't duplicate the work 
    141143        # The reason for the kwargs check is that standard iterator passes in by 
    142         # args, and nstantiation for iteration is 33% faster. 
     144        # args, and instantiation for iteration is 33% faster. 
    143145        args_len = len(args) 
    144146        if args_len > len(self._meta.fields): 
  • django/branches/queryset-refactor/django/newforms/forms.py

    r7029 r7124  
    2222    name = name[0].upper() + name[1:] 
    2323    return name.replace('_', ' ') 
     24 
     25def get_declared_fields(bases, attrs, with_base_fields=True): 
     26    """ 
     27    Create a list of form field instances from the passed in 'attrs', plus any 
     28    similar fields on the base classes (in 'bases'). This is used by both the 
     29    Form and ModelForm metclasses. 
     30 
     31    If 'with_base_fields' is True, all fields from the bases are used. 
     32    Otherwise, only fields in the 'declared_fields' attribute on the bases are 
     33    used. The distinction is useful in ModelForm subclassing. 
     34    """ 
     35    fields = [(field_name, attrs.pop(field_name)) for field_name, obj in attrs.items() if isinstance(obj, Field)] 
     36    fields.sort(lambda x, y: cmp(x[1].creation_counter, y[1].creation_counter)) 
     37 
     38    # If this class is subclassing another Form, add that Form's fields. 
     39    # Note that we loop over the bases in *reverse*. This is necessary in 
     40    # order to preserve the correct order of fields. 
     41    if with_base_fields: 
     42        for base in bases[::-1]: 
     43            if hasattr(base, 'base_fields'): 
     44                fields = base.base_fields.items() + fields 
     45    else: 
     46        for base in bases[::-1]: 
     47            if hasattr(base, 'declared_fields'): 
     48                fields = base.declared_fields.items() + fields 
     49 
     50    return SortedDict(fields) 
    2451 
    2552class DeclarativeFieldsMetaclass(type): 
     
    2956    """ 
    3057    def __new__(cls, name, bases, attrs): 
    31         fields = [(field_name, attrs.pop(field_name)) for field_name, obj in attrs.items() if isinstance(obj, Field)] 
    32         fields.sort(lambda x, y: cmp(x[1].creation_counter, y[1].creation_counter)) 
    33  
    34         # If this class is subclassing another Form, add that Form's fields. 
    35         # Note that we loop over the bases in *reverse*. This is necessary in 
    36         # order to preserve the correct order of fields. 
    37         for base in bases[::-1]: 
    38             if hasattr(base, 'base_fields'): 
    39                 fields = base.base_fields.items() + fields 
    40  
    41         attrs['base_fields'] = SortedDict(fields) 
     58        attrs['base_fields'] = get_declared_fields(bases, attrs) 
    4259        return type.__new__(cls, name, bases, attrs) 
    4360 
  • django/branches/queryset-refactor/django/newforms/models.py

    r7086 r7124  
    1212 
    1313from util import ValidationError, ErrorList 
    14 from forms import BaseForm 
     14from forms import BaseForm, get_declared_fields 
    1515from fields import Field, ChoiceField, EMPTY_VALUES 
    1616from widgets import Select, SelectMultiple, MultipleHiddenInput 
     
    212212        self.exclude = getattr(options, 'exclude', None) 
    213213 
     214 
    214215class ModelFormMetaclass(type): 
    215216    def __new__(cls, name, bases, attrs, 
    216217                formfield_callback=lambda f: f.formfield()): 
    217         fields = [(field_name, attrs.pop(field_name)) for field_name, obj in attrs.items() if isinstance(obj, Field)] 
    218         fields.sort(lambda x, y: cmp(x[1].creation_counter, y[1].creation_counter)) 
    219  
    220         # If this class is subclassing another Form, add that Form's fields. 
    221         # Note that we loop over the bases in *reverse*. This is necessary in 
    222         # order to preserve the correct order of fields. 
    223         for base in bases[::-1]: 
    224             if hasattr(base, 'base_fields'): 
    225                 fields = base.base_fields.items() + fields 
    226         declared_fields = SortedDict(fields) 
    227  
    228         opts = ModelFormOptions(attrs.get('Meta', None)) 
    229         attrs['_meta'] = opts 
    230  
    231         # Don't allow more than one Meta model definition in bases. The fields 
    232         # would be generated correctly, but the save method won't deal with 
    233         # more than one object. 
    234         base_models = [] 
    235         for base in bases: 
    236             base_opts = getattr(base, '_meta', None) 
    237             base_model = getattr(base_opts, 'model', None) 
    238             if base_model is not None: 
    239                 base_models.append(base_model) 
    240         if len(base_models) > 1: 
    241             raise ImproperlyConfigured("%s's base classes define more than one model." % name) 
    242  
    243         # If a model is defined, extract form fields from it and add them to base_fields 
    244         if attrs['_meta'].model is not None: 
    245             # Don't allow a subclass to define a different Meta model than a 
    246             # parent class has. Technically the right fields would be generated, 
    247             # but the save method will not deal with more than one model. 
    248             for base in bases: 
    249                 base_opts = getattr(base, '_meta', None) 
    250                 base_model = getattr(base_opts, 'model', None) 
    251                 if base_model and base_model is not opts.model: 
    252                     raise ImproperlyConfigured('%s defines a different model than its parent.' % name) 
    253             model_fields = fields_for_model(opts.model, opts.fields, 
    254                     opts.exclude, formfield_callback) 
    255             # fields declared in base classes override fields from the model 
    256             model_fields.update(declared_fields) 
    257             attrs['base_fields'] = model_fields 
     218        try: 
     219            parents = [b for b in bases if issubclass(b, ModelForm)] 
     220        except NameError: 
     221            # We are defining ModelForm itself. 
     222            parents = None 
     223        if not parents: 
     224            return super(ModelFormMetaclass, cls).__new__(cls, name, bases, 
     225                    attrs) 
     226 
     227        new_class = type.__new__(cls, name, bases, attrs) 
     228        declared_fields = get_declared_fields(bases, attrs, False) 
     229        opts = new_class._meta = ModelFormOptions(getattr(new_class, 'Meta', None)) 
     230        if opts.model: 
     231            # If a model is defined, extract form fields from it. 
     232            fields = fields_for_model(opts.model, opts.fields, 
     233                                      opts.exclude, formfield_callback) 
     234            # Override default model fields with any custom declared ones 
     235            # (plus, include all the other declared fields). 
     236            fields.update(declared_fields) 
    258237        else: 
    259             attrs['base_fields'] = declared_fields 
    260         return type.__new__(cls, name, bases, attrs) 
     238            fields = declared_fields 
     239        new_class.declared_fields = declared_fields 
     240        new_class.base_fields = fields 
     241        return new_class 
    261242 
    262243class BaseModelForm(BaseForm): 
    263244    def __init__(self, data=None, files=None, auto_id='id_%s', prefix=None, 
    264                  initial=None, error_class=ErrorList, label_suffix=':', instance=None): 
     245                 initial=None, error_class=ErrorList, label_suffix=':', 
     246                 instance=None): 
    265247        opts = self._meta 
    266248        if instance is None: 
     
    278260    def save(self, commit=True): 
    279261        """ 
    280         Saves this ``form``'s cleaned_data into model instance ``self.instance``. 
     262        Saves this ``form``'s cleaned_data into model instance 
     263        ``self.instance``. 
    281264 
    282265        If commit=True, then the changes to ``instance`` will be saved to the 
  • django/branches/queryset-refactor/django/utils/datastructures.py

    r7086 r7124  
    44    up values in more than one dictionary, passed in the constructor. 
    55 
    6     If a key appears in more than one of the passed in dictionaries, only the 
     6    If a key appears in more than one of the given dictionaries, only the 
    77    first occurrence will be used. 
    88    """ 
  • django/branches/queryset-refactor/docs/api_stability.txt

    r5818 r7124  
    8989 
    9090   - Generic relations will most likely be moved out of core and into the 
    91      content-types contrib package to avoid core dependancies on optional 
     91     content-types contrib package to avoid core dependencies on optional 
    9292     components. 
    9393 
  • django/branches/queryset-refactor/docs/contenttypes.txt

    r6341 r7124  
    216216creating a ``TaggedItem``:: 
    217217 
    218     >>> from django.contrib.models.auth import User 
     218    >>> from django.contrib.auth.models import User 
    219219    >>> guido = User.objects.get(username='Guido') 
    220220    >>> t = TaggedItem(content_object=guido, tag='bdfl') 
     
    236236be used to retrieve their associated ``TaggedItems``:: 
    237237 
    238     >>> b = Bookmark('http://www.djangoproject.com/') 
     238    >>> b = Bookmark(url='http://www.djangoproject.com/') 
    239239    >>> b.save() 
    240240    >>> t1 = TaggedItem(content_object=b, tag='django') 
  • django/branches/queryset-refactor/docs/distributions.txt

    r7029 r7124  
    66with their package-management systems. These can make installation and upgrading 
    77much easier for users of Django since the integration includes the ability to 
    8 automatically install dependancies (like database adapters) that Django 
     8automatically install dependencies (like database adapters) that Django 
    99requires. 
    1010 
  • django/branches/queryset-refactor/docs/django-admin.txt

    r7004 r7124  
    718718 
    719719Note that this option is unnecessary in ``manage.py``, because it uses 
    720 ``settings.py`` from the current project by default.  
     720``settings.py`` from the current project by default. 
    721721 
    722722Extra niceties 
     
    766766                explode.py 
    767767        views.py 
    768          
     768 
    769769In this example, the ``explode`` command will be made available to any project 
    770 that includes the ``fancy_blog`` application in ``settings.INSTALLED_APPS``. 
     770that includes the ``blog`` application in ``settings.INSTALLED_APPS``. 
    771771 
    772772The ``explode.py`` module has only one requirement -- it must define a class 
  • django/branches/queryset-refactor/docs/install.txt

    r6954 r7124  
    139139platform/distribution provides official Django packages/installers. 
    140140Distribution-provided packages will typically allow for automatic 
    141 installation of dependancies and easy upgrade paths. 
     141installation of dependencies and easy upgrade paths. 
    142142 
    143143Installing an official release 
  • django/branches/queryset-refactor/docs/model-api.txt

    r7096 r7124  
    385385~~~~~~~~~~~~~~~~~~ 
    386386 
    387 An IP address, in string format (i.e. "24.124.1.30"). 
     387An IP address, in string format (e.g. "192.0.2.30"). 
    388388 
    389389The admin represents this as an ``<input type="text">`` (a single-line input). 
     
    953953 
    954954    ``symmetrical``          Only used in the definition of ManyToManyFields on self. 
    955                              Consider the following model: 
    956  
    957                              class Person(models.Model): 
    958                                  friends = models.ManyToManyField("self") 
     955                             Consider the following model:: 
     956 
     957                                 class Person(models.Model): 
     958                                     friends = models.ManyToManyField("self") 
    959959 
    960960                             When Django processes this model, it identifies that it has 
     
    18721872If you define a ``__unicode__()`` method on your model and not a ``__str__()`` 
    18731873method, Django will automatically provide you with a ``__str__()`` that calls 
    1874 ``__unicode()__`` and then converts the result correctly to a UTF-8 encoded 
     1874``__unicode__()`` and then converts the result correctly to a UTF-8 encoded 
    18751875string object. This is recommended development practice: define only 
    18761876``__unicode__()`` and let Django take care of the conversion to string objects 
  • django/branches/queryset-refactor/docs/modelforms.txt

    r7086 r7124  
    321321   ...     class Meta: 
    322322   ...         model = Article 
     323 
     324Form inheritance 
     325---------------- 
     326 
     327As with basic forms, you can extend and reuse ``ModelForms`` by inheriting 
     328them. This is useful if you need to declare extra fields or extra methods on a 
     329parent class for use in a number of forms derived from models. For example, 
     330using the previous ``ArticleForm`` class:: 
     331 
     332    >>> class EnhancedArticleForm(ArticleForm): 
     333    ...     def clean_pub_date(self): 
     334    ...         ... 
     335 
     336This creates a form that behaves identically to ``ArticleForm``, except there's 
     337some extra validation and cleaning for the ``pub_date`` field. 
     338 
     339You can also subclass the parent's ``Meta`` inner class if you want to change 
     340the ``Meta.fields`` or ``Meta.excludes`` lists:: 
     341 
     342    >>> class RestrictedArticleForm(EnhancedArticleForm): 
     343    ...     class Meta(ArticleForm.Meta): 
     344    ...         exclude = ['body'] 
     345 
     346This adds the extra method from the ``EnhancedArticleForm`` and modifies 
     347the original ``ArticleForm.Meta`` to remove one field. 
     348 
     349There are a couple of things to note, however. 
     350 
     351 * Normal Python name resolution rules apply. If you have multiple base 
     352   classes that declare a ``Meta`` inner class, only the first one will be 
     353   used. This means the child's ``Meta``, if it exists, otherwise the 
     354   ``Meta`` of the first parent, etc. 
     355 
     356 * For technical reasons, a subclass cannot inherit from both a ``ModelForm`` 
     357   and a ``Form`` simultaneously. 
     358 
     359Chances are these notes won't affect you unless you're trying to do something 
     360tricky with subclassing. 
  • django/branches/queryset-refactor/docs/request_response.txt

    r7086 r7124  
    577577 
    578578    * The 404 view is passed a ``RequestContext`` and will have access to 
    579       variables supplied by your ``TEMPLATE_CONTEXT_PROCESSORS`` (e.g. 
     579      variables supplied by your ``TEMPLATE_CONTEXT_PROCESSORS`` setting (e.g., 
    580580      ``MEDIA_URL``). 
    581581 
  • django/branches/queryset-refactor/docs/shortcuts.txt

    r7086 r7124  
    3131    The context instance to render the template with. By default, the template 
    3232    will be rendered with a ``Context`` instance (filled with values from 
    33     ``dictionary``). If you need to use `context processors`_, you will want to 
    34     render the template with a ``RequestContext`` instance instead. Your code 
    35     might look something like this:: 
     33    ``dictionary``). If you need to use `context processors`_, render the 
     34    template with a ``RequestContext`` instance instead. Your code might look 
     35    something like this:: 
    3636 
    3737        return render_to_response('my_template.html', 
  • django/branches/queryset-refactor/docs/templates.txt

    r7029 r7124  
    14071407~~~~ 
    14081408 
     1409**New in Django development version.** 
     1410 
    14091411Returns the last item in a list. 
    14101412 
  • django/branches/queryset-refactor/docs/url_dispatch.txt

    r6753 r7124  
    191191`Passing extra options to view functions`_ below.) 
    192192 
     193.. note:: 
     194    Because `patterns()` is a function call, it accepts a maximum of 255 
     195    arguments (URL patterns, in this case). This is a limit for all Python 
     196    function calls. This is rarely a problem in practice, because you'll 
     197    typically structure your URL patterns modularly by using `include()` 
     198    sections. However, on the off-chance you do hit the 255-argument limit, 
     199    realize that `patterns()` returns a Python list, so you can split up the 
     200    construction of the list. 
     201 
     202    :: 
     203 
     204        urlpatterns = patterns('', 
     205            ... 
     206            ) 
     207        urlpatterns += patterns('', 
     208            ... 
     209            ) 
     210 
     211    Python lists have unlimited size, so there's no limit to how many URL 
     212    patterns you can construct. The only limit is that you can only create 254 
     213    at a time (the 255th argument is the initial prefix argument). 
     214 
    193215url 
    194216--- 
  • django/branches/queryset-refactor/tests/modeltests/model_forms/models.py

    r7029 r7124  
    6565    def __unicode__(self): 
    6666        return self.description 
    67          
     67 
    6868class ImageFile(models.Model): 
    6969    description = models.CharField(max_length=20) 
    7070    image = models.FileField(upload_to=tempfile.gettempdir()) 
    71      
     71 
    7272    def __unicode__(self): 
    7373        return self.description 
     
    156156...         model = Category 
    157157 
    158 >>> class BadForm(CategoryForm): 
    159 ...     class Meta: 
    160 ...         model = Article 
    161 Traceback (most recent call last): 
    162 ... 
    163 ImproperlyConfigured: BadForm defines a different model than its parent. 
     158>>> class OddForm(CategoryForm): 
     159...     class Meta: 
     160...         model = Article 
     161 
     162OddForm is now an Article-related thing, because BadForm.Meta overrides 
     163CategoryForm.Meta. 
     164>>> OddForm.base_fields.keys() 
     165['headline', 'slug', 'pub_date', 'writer', 'article', 'status', 'categories'] 
    164166 
    165167>>> class ArticleForm(ModelForm): 
    166168...     class Meta: 
    167169...         model = Article 
     170 
     171First class with a Meta class wins. 
    168172 
    169173>>> class BadForm(ArticleForm, CategoryForm): 
    170174...     pass 
    171 Traceback (most recent call last): 
    172 ... 
    173 ImproperlyConfigured: BadForm's base classes define more than one model. 
    174  
    175 This one is OK since the subclass specifies the same model as the parent. 
    176  
     175>>> OddForm.base_fields.keys() 
     176['headline', 'slug', 'pub_date', 'writer', 'article', 'status', 'categories'] 
     177 
     178Subclassing without specifying a Meta on the class will use the parent's Meta 
     179(or the first parent in the MRO if there are multiple parent classes). 
     180 
     181>>> class CategoryForm(ModelForm): 
     182...     class Meta: 
     183...         model = Category 
    177184>>> class SubCategoryForm(CategoryForm): 
    178 ...     class Meta: 
    179 ...         model = Category 
    180  
     185...     pass 
     186>>> SubCategoryForm.base_fields.keys() 
     187['name', 'slug', 'url'] 
     188 
     189We can also subclass the Meta inner class to change the fields list. 
     190 
     191>>> class CategoryForm(ModelForm): 
     192...     checkbox = forms.BooleanField() 
     193... 
     194...     class Meta: 
     195...         model = Category 
     196>>> class SubCategoryForm(CategoryForm): 
     197...     class Meta(CategoryForm.Meta): 
     198...         exclude = ['url'] 
     199 
     200>>> print SubCategoryForm() 
     201<tr><th><label for="id_name">Name:</label></th><td><input id="id_name" type="text" name="name" maxlength="20" /></td></tr> 
     202<tr><th><label for="id_slug">Slug:</label></th><td><input id="id_slug" type="text" name="slug" maxlength="20" /></td></tr> 
     203<tr><th><label for="id_checkbox">Checkbox:</label></th><td><input type="checkbox" name="checkbox" id="id_checkbox" /></td></tr> 
    181204 
    182205# Old form_for_x tests ####################################################### 
  • django/branches/queryset-refactor/tests/modeltests/ordering/models.py

    r6599 r7124  
    33 
    44Specify default ordering for a model using the ``ordering`` attribute, which 
    5 should be a list or tuple of field names. This tells Django how to order the 
    6 results of ``get_list()`` and other similar functions. 
     5should be a list or tuple of field names. This tells Django how to order 
     6queryset results. 
    77 
    88If a field name in ``ordering`` starts with a hyphen, that field will be 
  • django/branches/queryset-refactor/tests/regressiontests/i18n/misc.py

    r7099 r7124  
     1import sys 
     2 
    13tests = """ 
    24>>> from django.utils.translation.trans_real import parse_accept_lang_header 
     
    8486>>> g(r) 
    8587'es-ar' 
     88""" 
    8689 
     90# Python 2.3 returns slightly different results for completely bogus locales, 
     91# so we omit this test for that anything below 2.4. It's relatively harmless in 
     92# any cases (GIGO). This also means this won't be executed on Jython currently, 
     93# but life's like that sometimes. 
     94if sys.version_info >= (2, 4): 
     95    tests += """ 
    8796This test assumes there won't be a Django translation to a US variation 
    8897of the Spanish language, a safe assumption. When the user sets it 
     
    92101>>> g(r) 
    93102'es' 
     103""" 
    94104 
     105tests += """ 
    95106This tests the following scenario: there isn't a main language (zh) 
    96107translation of Django but there is a translation to variation (zh_CN)