When saving, how can you check if a field has changed?

前端 未结 25 1831
鱼传尺愫
鱼传尺愫 2020-11-22 07:15

In my model I have :

class Alias(MyBaseModel):
    remote_image = models.URLField(max_length=500, null=True, help_text=\"A URL that is downloaded and cached          


        
25条回答
  •  情话喂你
    2020-11-22 07:35

    A modification to @ivanperelivskiy's answer:

    @property
    def _dict(self):
        ret = {}
        for field in self._meta.get_fields():
            if isinstance(field, ForeignObjectRel):
                # foreign objects might not have corresponding objects in the database.
                if hasattr(self, field.get_accessor_name()):
                    ret[field.get_accessor_name()] = getattr(self, field.get_accessor_name())
                else:
                    ret[field.get_accessor_name()] = None
            else:
                ret[field.attname] = getattr(self, field.attname)
        return ret
    

    This uses django 1.10's public method get_fields instead. This makes the code more future proof, but more importantly also includes foreign keys and fields where editable=False.

    For reference, here is the implementation of .fields

    @cached_property
    def fields(self):
        """
        Returns a list of all forward fields on the model and its parents,
        excluding ManyToManyFields.
    
        Private API intended only to be used by Django itself; get_fields()
        combined with filtering of field properties is the public API for
        obtaining this field list.
        """
        # For legacy reasons, the fields property should only contain forward
        # fields that are not private or with a m2m cardinality. Therefore we
        # pass these three filters as filters to the generator.
        # The third lambda is a longwinded way of checking f.related_model - we don't
        # use that property directly because related_model is a cached property,
        # and all the models may not have been loaded yet; we don't want to cache
        # the string reference to the related_model.
        def is_not_an_m2m_field(f):
            return not (f.is_relation and f.many_to_many)
    
        def is_not_a_generic_relation(f):
            return not (f.is_relation and f.one_to_many)
    
        def is_not_a_generic_foreign_key(f):
            return not (
                f.is_relation and f.many_to_one and not (hasattr(f.remote_field, 'model') and f.remote_field.model)
            )
    
        return make_immutable_fields_list(
            "fields",
            (f for f in self._get_fields(reverse=False)
             if is_not_an_m2m_field(f) and is_not_a_generic_relation(f) and is_not_a_generic_foreign_key(f))
        )
    

提交回复
热议问题