django之relacted.py(探秘django的关联field)

Posted on 2018-03-31 17:19  王将军之武库  阅读(277)  评论(0编辑  收藏  举报

生成model类对象时,传入的每个field对象都会调用其contribute_to_class函数,生成对应的属性。

def contribute_to_class(self, cls, name, virtual_only=False):

        super(RelatedField, self).contribute_to_class(cls, name, virtual_only=virtual_only)

        self.opts = cls._meta

        if not cls._meta.abstract:
            if self.remote_field.related_name:
                related_name = force_text(self.remote_field.related_name) % {
                    'class': cls.__name__.lower(),
                    'app_label': cls._meta.app_label.lower()
                }
                self.remote_field.related_name = related_name

            def resolve_related_class(model, related, field):#如果是关联field的话,会对关联model产生动作
                field.remote_field.model = related
                field.do_related_class(related, model)
            lazy_related_operation(resolve_related_class, cls, self.remote_field.model, field=self)
field.do_related_class(related, model)
def do_related_class(self, other, cls):
        self.set_attributes_from_rel()
        self.contribute_to_related_class(other, self.remote_field)

def set_attributes_from_rel(self):
        self.name = (
            self.name or
            (self.remote_field.model._meta.model_name + '_' + self.remote_field.model._meta.pk.name)
        )
        if self.verbose_name is None:
            self.verbose_name = self.remote_field.model._meta.verbose_name
        self.remote_field.set_field_name()#设置了远程field的名字

def contribute_to_related_class(self, cls, related):#related为远程filed
        # Internal FK's - i.e., those with a related name ending with '+' -
        # and swapped models don't get a related descriptor.
        if not self.remote_field.is_hidden() and not related.related_model._meta.swapped:
#为关联model设置了一个属性:category = models.ForeignKey(Category, related_name='forums'
#Category.category_id的属性related_accessor_class,然后就可以调用related_accessor_class
#add,remove等函数

setattr(cls, related.get_accessor_name(), self.related_accessor_class(related))
# While 'limit_choices_to' might be a callable, simply pass # it along for later - this is too early because it's still # model load time. if self.remote_field.limit_choices_to: cls._meta.related_fkey_lookups.append(self.remote_field.limit_choices_to)

 

Copyright © 2024 王将军之武库
Powered by .NET 9.0 on Kubernetes