Django

Code

Ticket #2248: inline_models_in_Admin.diff

File inline_models_in_Admin.diff, 5.6 kB (added by joaoma@gmail.com, 2 years ago)

patch for the new inline_models syntax

  • django/db/models/base.py

    old new  
    1717import types 
    1818import sys 
    1919import os 
     20try: 
     21    from threading import local 
     22except ImportError: 
     23    from django.utils._threading_local import local 
     24 
     25_thread_locals = local() 
     26 
     27# This code is needed because we can't connect to the 
     28# related inline_models' class prepared signals. 
     29# At the time of class_prepared, the followed model 
     30# isn't known to Python. So, we store the inline_models 
     31# info in a variable inside threadlocals 
     32_thread_locals.inline_models_info = {} 
     33 
     34def inline_models_on_class_prepared(**kw_args): 
     35    sender = kw_args['sender'] 
     36    sender_fqn = "%s.%s" % (sender.__module__,sender.__name__) 
     37    if sender_fqn in _thread_locals.inline_models_info:  
     38        for inline_info in _thread_locals.inline_models_info[sender_fqn]: 
     39            parent_model = inline_info['parent_model'] 
     40            rel_fieldname = inline_info.get('related_field',None) 
     41            if rel_fieldname: 
     42                rel_field = sender._meta.get_field(rel_fieldname)  
     43            else: 
     44                fields = [x for x in sender._meta.fields if x.rel] 
     45                rel_field = [x for x in fields if  x.rel.to==parent_model][0] 
     46            for key,val in inline_info.iteritems(): 
     47                if key=='type': 
     48                    rel_field.rel.edit_inline = val 
     49                elif key=='fields': 
     50                    for field in sender._meta.fields: 
     51                        if field.name != rel_field.name: 
     52                            field.core = field.name in val 
     53                elif hasattr(rel_field.rel,key): 
     54                    setattr(rel_field.rel,key,val) 
     55        del _thread_locals.inline_models_info[sender_fqn]             
     56 
     57dispatcher.connect(inline_models_on_class_prepared, 
     58           signal=signals.class_prepared) 
     59# End of inline_models handling 
    2060 
    2161class ModelBase(type): 
    2262    "Metaclass for all models" 
     
    151191        if hasattr(cls, 'get_absolute_url'): 
    152192            cls.get_absolute_url = curry(get_absolute_url, opts, cls.get_absolute_url) 
    153193 
     194        # Check the inline_models option 
     195        # and put the corresponding entry in the threadlocals var  
     196        # when needed 
     197        if cls._meta.admin: 
     198            for inline_info in cls._meta.admin.inline_models: 
     199                model_name = inline_info['model'] 
     200                if '.' not in model_name: 
     201                    model_fqn = "%s.%s" % (cls.__module__,model_name) 
     202                else: 
     203                    model_fqn = model_name 
     204                inline_info.update(parent_model=cls) 
     205                if _thread_locals.inline_models_info.get(model_fqn,None): 
     206                    _thread_locals.inline_models_info[model_fqn].append(inline_info) 
     207                else: 
     208                    _thread_locals.inline_models_info[model_fqn] = [inline_info] 
     209 
    154210        dispatcher.send(signal=signals.class_prepared, sender=cls) 
    155211 
    156212    _prepare = classmethod(_prepare) 
  • django/db/models/options.py

    old new  
    201201class AdminOptions(object): 
    202202    def __init__(self, fields=None, js=None, list_display=None, list_filter=None, 
    203203        date_hierarchy=None, save_as=False, ordering=None, search_fields=None, 
    204         save_on_top=False, list_select_related=False, manager=None, list_per_page=100): 
     204        save_on_top=False, list_select_related=False, manager=None, list_per_page=100, 
     205        inline_models=[]): 
    205206        self.fields = fields 
    206207        self.js = js or [] 
    207208        self.list_display = list_display or ['__str__'] 
     
    212213        self.save_on_top = save_on_top 
    213214        self.list_select_related = list_select_related 
    214215        self.list_per_page = list_per_page 
     216        self.inline_models = inline_models 
    215217        self.manager = manager or Manager() 
    216218 
    217219    def get_field_sets(self, opts): 
  • django/docs/model-api.txt

    old new  
    11761176under the heading of the fieldset. It's used verbatim, so you can use any HTML 
    11771177and you must escape any special HTML characters (such as ampersands) yourself. 
    11781178 
     1179``inline_models`` 
     1180----------------- 
     1181A list of dicts that define which related models should be edited inline with 
     1182the given model. It's a cleaner alternative to edit_inline, with the 
     1183following differences: 
     1184  - You define the model with the 'model' keyword argument. You have to use 
     1185    the model as a ``string``, not the ``class``. 
     1186  - You can use the 'related_field' keyword to define the related model's 
     1187    ForeignKey that will be used, or leave Django to catch the first 
     1188    ForeignKey field to the parent model. 
     1189  - Instead of the 'edit_inline' keyword, you use the 'type' keyword. 
     1190  - Instead of specifying core=True in each field you want to show in 
     1191    the inline admin, you use the 'fields' keyword argument, which is 
     1192    a list of fields 
     1193All other options can be used, e.g. ``min_num_in_admin``. 
     1194 
     1195Example:: 
     1196    inline_models = ( 
     1197        {'model':'InlineModel', 
     1198         'type':models.TABULAR, 
     1199         'min_num_in_admin':1, 
     1200         'num_extra_on_change':1, 
     1201         'fields':('field1','field2','field3') 
     1202        }, 
     1203    ) 
     1204 
     1205Check the ``edit_inline`` section for more arguments on this option. 
     1206 
    11791207``js`` 
    11801208------ 
    11811209