Changeset 7124
- Timestamp:
- 02/16/08 00:57:52 (8 months ago)
- Files:
-
- django/branches/queryset-refactor/AUTHORS (modified) (1 diff)
- django/branches/queryset-refactor/django/conf/global_settings.py (modified) (1 diff)
- django/branches/queryset-refactor/django/conf/locale/eu (added)
- django/branches/queryset-refactor/django/conf/locale/eu/LC_MESSAGES (added)
- django/branches/queryset-refactor/django/conf/locale/eu/LC_MESSAGES/djangojs.mo (added)
- django/branches/queryset-refactor/django/conf/locale/eu/LC_MESSAGES/djangojs.po (added)
- django/branches/queryset-refactor/django/conf/locale/eu/LC_MESSAGES/django.mo (added)
- django/branches/queryset-refactor/django/conf/locale/eu/LC_MESSAGES/django.po (added)
- django/branches/queryset-refactor/django/core/management/commands/sqlall.py (modified) (1 diff)
- django/branches/queryset-refactor/django/db/models/base.py (modified) (2 diffs)
- django/branches/queryset-refactor/django/newforms/forms.py (modified) (2 diffs)
- django/branches/queryset-refactor/django/newforms/models.py (modified) (3 diffs)
- django/branches/queryset-refactor/django/utils/datastructures.py (modified) (1 diff)
- django/branches/queryset-refactor/docs/api_stability.txt (modified) (1 diff)
- django/branches/queryset-refactor/docs/contenttypes.txt (modified) (2 diffs)
- django/branches/queryset-refactor/docs/distributions.txt (modified) (1 diff)
- django/branches/queryset-refactor/docs/django-admin.txt (modified) (2 diffs)
- django/branches/queryset-refactor/docs/install.txt (modified) (1 diff)
- django/branches/queryset-refactor/docs/model-api.txt (modified) (3 diffs)
- django/branches/queryset-refactor/docs/modelforms.txt (modified) (1 diff)
- django/branches/queryset-refactor/docs/request_response.txt (modified) (1 diff)
- django/branches/queryset-refactor/docs/shortcuts.txt (modified) (1 diff)
- django/branches/queryset-refactor/docs/templates.txt (modified) (1 diff)
- django/branches/queryset-refactor/docs/url_dispatch.txt (modified) (1 diff)
- django/branches/queryset-refactor/tests/modeltests/model_forms/models.py (modified) (2 diffs)
- django/branches/queryset-refactor/tests/modeltests/ordering/models.py (modified) (1 diff)
- django/branches/queryset-refactor/tests/regressiontests/i18n/misc.py (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
django/branches/queryset-refactor/AUTHORS
r7086 r7124 169 169 Jason Huggins <http://www.jrandolph.com/blog/> 170 170 Hyun Mi Ae 171 Ibon <ibonso@gmail.com> 171 172 Tom Insam 172 173 Baurzhan Ismagulov <ibr@radix50.net> django/branches/queryset-refactor/django/conf/global_settings.py
r7099 r7124 49 49 ('es', gettext_noop('Spanish')), 50 50 ('es-ar', gettext_noop('Argentinean Spanish')), 51 ('eu', gettext_noop('Basque')), 51 52 ('fa', gettext_noop('Persian')), 52 53 ('fi', gettext_noop('Finnish')), django/branches/queryset-refactor/django/core/management/commands/sqlall.py
r5898 r7124 2 2 3 3 class Command(AppCommand): 4 help = "Prints the CREATE TABLE, initial-dataand 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)." 5 5 6 6 output_transaction = True django/branches/queryset-refactor/django/db/models/base.py
r7099 r7124 42 42 # Build complete list of parents 43 43 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'): 45 47 new_class._meta.parents.append(base) 46 48 new_class._meta.parents.extend(base._meta.parents) … … 140 142 # overrides it. It should be one or the other; don't duplicate the work 141 143 # 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. 143 145 args_len = len(args) 144 146 if args_len > len(self._meta.fields): django/branches/queryset-refactor/django/newforms/forms.py
r7029 r7124 22 22 name = name[0].upper() + name[1:] 23 23 return name.replace('_', ' ') 24 25 def 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) 24 51 25 52 class DeclarativeFieldsMetaclass(type): … … 29 56 """ 30 57 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) 42 59 return type.__new__(cls, name, bases, attrs) 43 60 django/branches/queryset-refactor/django/newforms/models.py
r7086 r7124 12 12 13 13 from util import ValidationError, ErrorList 14 from forms import BaseForm 14 from forms import BaseForm, get_declared_fields 15 15 from fields import Field, ChoiceField, EMPTY_VALUES 16 16 from widgets import Select, SelectMultiple, MultipleHiddenInput … … 212 212 self.exclude = getattr(options, 'exclude', None) 213 213 214 214 215 class ModelFormMetaclass(type): 215 216 def __new__(cls, name, bases, attrs, 216 217 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) 258 237 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 261 242 262 243 class BaseModelForm(BaseForm): 263 244 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): 265 247 opts = self._meta 266 248 if instance is None: … … 278 260 def save(self, commit=True): 279 261 """ 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``. 281 264 282 265 If commit=True, then the changes to ``instance`` will be saved to the django/branches/queryset-refactor/django/utils/datastructures.py
r7086 r7124 4 4 up values in more than one dictionary, passed in the constructor. 5 5 6 If a key appears in more than one of the passed in dictionaries, only the6 If a key appears in more than one of the given dictionaries, only the 7 7 first occurrence will be used. 8 8 """ django/branches/queryset-refactor/docs/api_stability.txt
r5818 r7124 89 89 90 90 - Generic relations will most likely be moved out of core and into the 91 content-types contrib package to avoid core depend ancies on optional91 content-types contrib package to avoid core dependencies on optional 92 92 components. 93 93 django/branches/queryset-refactor/docs/contenttypes.txt
r6341 r7124 216 216 creating a ``TaggedItem``:: 217 217 218 >>> from django.contrib. models.authimport User218 >>> from django.contrib.auth.models import User 219 219 >>> guido = User.objects.get(username='Guido') 220 220 >>> t = TaggedItem(content_object=guido, tag='bdfl') … … 236 236 be used to retrieve their associated ``TaggedItems``:: 237 237 238 >>> b = Bookmark( 'http://www.djangoproject.com/')238 >>> b = Bookmark(url='http://www.djangoproject.com/') 239 239 >>> b.save() 240 240 >>> t1 = TaggedItem(content_object=b, tag='django') django/branches/queryset-refactor/docs/distributions.txt
r7029 r7124 6 6 with their package-management systems. These can make installation and upgrading 7 7 much easier for users of Django since the integration includes the ability to 8 automatically install depend ancies (like database adapters) that Django8 automatically install dependencies (like database adapters) that Django 9 9 requires. 10 10 django/branches/queryset-refactor/docs/django-admin.txt
r7004 r7124 718 718 719 719 Note 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. 721 721 722 722 Extra niceties … … 766 766 explode.py 767 767 views.py 768 768 769 769 In this example, the ``explode`` command will be made available to any project 770 that includes the `` fancy_blog`` application in ``settings.INSTALLED_APPS``.770 that includes the ``blog`` application in ``settings.INSTALLED_APPS``. 771 771 772 772 The ``explode.py`` module has only one requirement -- it must define a class django/branches/queryset-refactor/docs/install.txt
r6954 r7124 139 139 platform/distribution provides official Django packages/installers. 140 140 Distribution-provided packages will typically allow for automatic 141 installation of depend ancies and easy upgrade paths.141 installation of dependencies and easy upgrade paths. 142 142 143 143 Installing an official release django/branches/queryset-refactor/docs/model-api.txt
r7096 r7124 385 385 ~~~~~~~~~~~~~~~~~~ 386 386 387 An IP address, in string format ( i.e. "24.124.1.30").387 An IP address, in string format (e.g. "192.0.2.30"). 388 388 389 389 The admin represents this as an ``<input type="text">`` (a single-line input). … … 953 953 954 954 ``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") 959 959 960 960 When Django processes this model, it identifies that it has … … 1872 1872 If you define a ``__unicode__()`` method on your model and not a ``__str__()`` 1873 1873 method, Django will automatically provide you with a ``__str__()`` that calls 1874 ``__unicode ()__`` and then converts the result correctly to a UTF-8 encoded1874 ``__unicode__()`` and then converts the result correctly to a UTF-8 encoded 1875 1875 string object. This is recommended development practice: define only 1876 1876 ``__unicode__()`` and let Django take care of the conversion to string objects django/branches/queryset-refactor/docs/modelforms.txt
r7086 r7124 321 321 ... class Meta: 322 322 ... model = Article 323 324 Form inheritance 325 ---------------- 326 327 As with basic forms, you can extend and reuse ``ModelForms`` by inheriting 328 them. This is useful if you need to declare extra fields or extra methods on a 329 parent class for use in a number of forms derived from models. For example, 330 using the previous ``ArticleForm`` class:: 331 332 >>> class EnhancedArticleForm(ArticleForm): 333 ... def clean_pub_date(self): 334 ... ... 335 336 This creates a form that behaves identically to ``ArticleForm``, except there's 337 some extra validation and cleaning for the ``pub_date`` field. 338 339 You can also subclass the parent's ``Meta`` inner class if you want to change 340 the ``Meta.fields`` or ``Meta.excludes`` lists:: 341 342 >>> class RestrictedArticleForm(EnhancedArticleForm): 343 ... class Meta(ArticleForm.Meta): 344 ... exclude = ['body'] 345 346 This adds the extra method from the ``EnhancedArticleForm`` and modifies 347 the original ``ArticleForm.Meta`` to remove one field. 348 349 There 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 359 Chances are these notes won't affect you unless you're trying to do something 360 tricky with subclassing. django/branches/queryset-refactor/docs/request_response.txt
r7086 r7124 577 577 578 578 * 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., 580 580 ``MEDIA_URL``). 581 581 django/branches/queryset-refactor/docs/shortcuts.txt
r7086 r7124 31 31 The context instance to render the template with. By default, the template 32 32 will be rendered with a ``Context`` instance (filled with values from 33 ``dictionary``). If you need to use `context processors`_, you will want to34 render the template with a ``RequestContext`` instance instead. Your code35 might looksomething 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:: 36 36 37 37 return render_to_response('my_template.html', django/branches/queryset-refactor/docs/templates.txt
r7029 r7124 1407 1407 ~~~~ 1408 1408 1409 **New in Django development version.** 1410 1409 1411 Returns the last item in a list. 1410 1412 django/branches/queryset-refactor/docs/url_dispatch.txt
r6753 r7124 191 191 `Passing extra options to view functions`_ below.) 192 192 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 193 215 url 194 216 --- django/branches/queryset-refactor/tests/modeltests/model_forms/models.py
r7029 r7124 65 65 def __unicode__(self): 66 66 return self.description 67 67 68 68 class ImageFile(models.Model): 69 69 description = models.CharField(max_length=20) 70 70 image = models.FileField(upload_to=tempfile.gettempdir()) 71 71 72 72 def __unicode__(self): 73 73 return self.description … … 156 156 ... model = Category 157 157 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 162 OddForm is now an Article-related thing, because BadForm.Meta overrides 163 CategoryForm.Meta. 164 >>> OddForm.base_fields.keys() 165 ['headline', 'slug', 'pub_date', 'writer', 'article', 'status', 'categories'] 164 166 165 167 >>> class ArticleForm(ModelForm): 166 168 ... class Meta: 167 169 ... model = Article 170 171 First class with a Meta class wins. 168 172 169 173 >>> class BadForm(ArticleForm, CategoryForm): 170 174 ... 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 178 Subclassing 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 177 184 >>> class SubCategoryForm(CategoryForm): 178 ... class Meta: 179 ... model = Category 180 185 ... pass 186 >>> SubCategoryForm.base_fields.keys() 187 ['name', 'slug', 'url'] 188 189 We 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> 181 204 182 205 # Old form_for_x tests ####################################################### django/branches/queryset-refactor/tests/modeltests/ordering/models.py
r6599 r7124 3 3 4 4 Specify 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 the6 results of ``get_list()`` and other similar functions.5 should be a list or tuple of field names. This tells Django how to order 6 queryset results. 7 7 8 8 If a field name in ``ordering`` starts with a hyphen, that field will be django/branches/queryset-refactor/tests/regressiontests/i18n/misc.py
r7099 r7124 1 import sys 2 1 3 tests = """ 2 4 >>> from django.utils.translation.trans_real import parse_accept_lang_header … … 84 86 >>> g(r) 85 87 'es-ar' 88 """ 86 89 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. 94 if sys.version_info >= (2, 4): 95 tests += """ 87 96 This test assumes there won't be a Django translation to a US variation 88 97 of the Spanish language, a safe assumption. When the user sets it … … 92 101 >>> g(r) 93 102 'es' 103 """ 94 104 105 tests += """ 95 106 This tests the following scenario: there isn't a main language (zh) 96 107 translation of Django but there is a translation to variation (zh_CN)
