Django

Code

Ticket #122: meta6.diff

File meta6.diff, 8.2 kB (added by mmarshall, 3 years ago)

Fixed a bug with relationship fields in the 'fields' attribute being duplicated. (oops)

  • django/core/meta.py

    old new  
    393393 
    394394class ModelBase(type): 
    395395    "Metaclass for all models" 
     396     
     397    # We need to keep track of Fields which are initiated inside of the class body, but 
     398    # not assined to an attribute.  (These could be ForeignKeys, ManyToManyFields, or 
     399    # OneToOneFields.) 
     400    _defined_fields_bank = {} 
     401     
    396402    def __new__(cls, name, bases, attrs): 
    397403        # If this isn't a subclass of Model, don't do anything special. 
    398404        if not bases: 
    399405            return type.__new__(cls, name, bases, attrs) 
    400406 
     407        # We must refactor the attributes around a little.  All Field class instances will be given 
     408        # names (as needed) and moved to the fields list.  All attributes of the Meta class will  
     409        # be moved into the main class attrs. 
     410 
     411        attrs["fields"] = attrs.has_key("fields") and list(attrs["fields"]) or [] 
     412 
     413        def handle_field(obj, name): 
     414            if isinstance(obj, Field):  #Check if this is a field 
     415                if isinstance(obj,(ForeignKey, ManyToManyField, OneToOneField)): 
     416                    obj.rel.name = name 
     417                else: 
     418                    obj.set_name(name) 
     419                attrs["fields"].append(obj) 
     420                return True 
     421            else: 
     422                return False 
     423 
     424        # loop through the attributes, and take out the fields. 
     425        for key in attrs.keys()[:]: 
     426            if handle_field(attrs[key], key): 
     427                del attrs[key]  # If the attr was added to fields, we want to delete it. 
     428 
     429        if attrs.has_key("Meta"): 
     430            for name in dir(attrs["Meta"]): 
     431                if name.startswith("__"): continue 
     432                if name in ("fields",): 
     433                    attrs[name].extend( getattr(attrs["Meta"],name) ) 
     434                else: 
     435                    attrs[name] = getattr(attrs["Meta"],name) 
     436            del attrs["Meta"] 
     437 
     438 
     439        # We don't want to duplicate relationship keys. 
     440        for field in attrs["fields"]: 
     441            if ModelBase._defined_fields_bank.has_key(id(field)): 
     442                del ModelBase._defined_fields_bank[id(field)] 
     443 
     444        # Add all of the relationship fields that were not assigned to an attribute. (or 
     445        # included in the "fields" attribute in the first place.) 
     446        attrs["fields"].extend( ModelBase._defined_fields_bank.values() ) 
     447        ModelBase._defined_fields_bank = {} 
     448 
     449        # Sort the fields, so that they appear in the correct order. 
     450        attrs["fields"].sort(lambda x,y: x.creation_counter - y.creation_counter) 
     451 
    401452        # If this model is a subclass of another Model, create an Options 
    402453        # object by first copying the base class's _meta and then updating it 
    403454        # with the overrides from this class. 
     
    15721623    # database level. 
    15731624    empty_strings_allowed = True 
    15741625 
    1575     def __init__(self, name, verbose_name=None, primary_key=False, 
     1626    # Will be increased each time a Field object is instanced.  Used to 
     1627    # retain the order of fields. 
     1628    creation_counter = 0 
     1629 
     1630    def __init__(self, name=None, verbose_name=None, primary_key=False, 
    15761631        maxlength=None, unique=False, blank=False, null=False, db_index=None, 
    15771632        core=False, rel=None, default=NOT_PROVIDED, editable=True, 
    15781633        prepopulate_from=None, unique_for_date=None, unique_for_month=None, 
    15791634        unique_for_year=None, validator_list=None, choices=None, radio_admin=None, 
    15801635        help_text=''): 
    15811636        self.name = name 
    1582         self.verbose_name = verbose_name or name.replace('_', ' ') 
     1637        self.original_verbose_name = verbose_name 
     1638        self.verbose_name = verbose_name or name and name.replace('_', ' ') 
    15831639        self.primary_key = primary_key 
    15841640        self.maxlength, self.unique = maxlength, unique 
    15851641        self.blank, self.null = blank, null 
     
    16041660        else: 
    16051661            self.db_index = db_index 
    16061662 
     1663        # Increase the creation counter, and save our local copy. 
     1664        self.creation_counter = Field.creation_counter 
     1665        Field.creation_counter += 1 
     1666 
     1667    def set_name(self, name ): 
     1668        """ 
     1669        Sets the name, and generates the verbose_name from it if needed. 
     1670        This function is here for when the name needs to be set later, (such as if it needs to be obtained from 
     1671        a the attribute name that stores the Field instance.) 
     1672        """ 
     1673        if not self.original_verbose_name: 
     1674            # If the verbose name was originally not specified, we will assume that  
     1675            # the user intends for the first argument passed to __init__ to be the verbose_name. 
     1676            self.verbose_name = self.name 
     1677             
     1678        self.name = name 
     1679        self.verbose_name = self.verbose_name or name and name.replace('_', ' ') 
     1680             
    16071681    def pre_save(self, obj, value, add): 
    16081682        """ 
    16091683        Hook for altering the object obj based on the value of this field and 
     
    17891863 
    17901864class DateField(Field): 
    17911865    empty_strings_allowed = False 
    1792     def __init__(self, name, verbose_name=None, auto_now=False, auto_now_add=False, **kwargs): 
     1866    def __init__(self, name=None, verbose_name=None, auto_now=False, auto_now_add=False, **kwargs): 
    17931867        self.auto_now, self.auto_now_add = auto_now, auto_now_add 
    17941868        if auto_now or auto_now_add: 
    17951869            kwargs['editable'] = False 
     
    18451919        return [formfields.EmailField] 
    18461920 
    18471921class FileField(Field): 
    1848     def __init__(self, name, verbose_name=None, upload_to='', **kwargs): 
     1922    def __init__(self, name=None, verbose_name=None, upload_to='', **kwargs): 
    18491923        self.upload_to = upload_to 
    18501924        Field.__init__(self, name, verbose_name, **kwargs) 
    18511925 
     
    19101984 
    19111985class FloatField(Field): 
    19121986    empty_strings_allowed = False 
    1913     def __init__(self, name, verbose_name=None, max_digits=None, decimal_places=None, **kwargs): 
     1987    def __init__(self, name=None, verbose_name=None, max_digits=None, decimal_places=None, **kwargs): 
    19141988        self.max_digits, self.decimal_places = max_digits, decimal_places 
    19151989        Field.__init__(self, name, verbose_name, **kwargs) 
    19161990 
     
    19922066 
    19932067class TimeField(Field): 
    19942068    empty_strings_allowed = False 
    1995     def __init__(self, name, verbose_name=None, auto_now=False, auto_now_add=False, **kwargs): 
     2069    def __init__(self, name=None, verbose_name=None, auto_now=False, auto_now_add=False, **kwargs): 
    19962070        self.auto_now, self.auto_now_add  = auto_now, auto_now_add 
    19972071        if auto_now or auto_now_add: 
    19982072            kwargs['editable'] = False 
     
    20192093        return [formfields.TimeField] 
    20202094 
    20212095class URLField(Field): 
    2022     def __init__(self, name, verbose_name=None, verify_exists=True, **kwargs): 
     2096    def __init__(self, name=None, verbose_name=None, verify_exists=True, **kwargs): 
    20232097        if verify_exists: 
    20242098            kwargs.setdefault('validator_list', []).append(validators.isExistingURL) 
    20252099        Field.__init__(self, name, verbose_name, **kwargs) 
     
    20322106        return [formfields.USStateField] 
    20332107 
    20342108class XMLField(Field): 
    2035     def __init__(self, name, verbose_name=None, schema_path=None, **kwargs): 
     2109    def __init__(self, name=None, verbose_name=None, schema_path=None, **kwargs): 
    20362110        self.schema_path = schema_path 
    20372111        Field.__init__(self, name, verbose_name, **kwargs) 
    20382112 
     
    20652139            lookup_overrides=kwargs.pop('lookup_overrides', None), 
    20662140            raw_id_admin=kwargs.pop('raw_id_admin', False)) 
    20672141        Field.__init__(self, **kwargs) 
     2142        ModelBase._defined_fields_bank[id(self)]=self 
    20682143 
    20692144    def get_manipulator_field_objs(self): 
    20702145        return [formfields.IntegerField] 
     
    20802155            filter_interface=kwargs.pop('filter_interface', None), 
    20812156            limit_choices_to=kwargs.pop('limit_choices_to', None)) 
    20822157        Field.__init__(self, **kwargs) 
     2158        ModelBase._defined_fields_bank[id(self)]=self 
    20832159 
    20842160    def get_manipulator_field_objs(self): 
    20852161        choices = self.get_choices(include_blank=False) 
     
    21052181            raw_id_admin=kwargs.pop('raw_id_admin', False)) 
    21062182        kwargs['primary_key'] = True 
    21072183        IntegerField.__init__(self, **kwargs) 
     2184        ModelBase._defined_fields_bank[id(self)]=self 
    21082185 
    21092186#################### 
    21102187# RELATIONSHIPS    #