2010-09-13 144 views
5

除了文档中的一个示例,我无法找到有关django如何选择名称的文档,以及可以从父对象访问子对象的名称。在他们的示例中,他们执行以下操作:django一对一关系如何将名称映射到子对象?

class Place(models.Model): 
     name = models.CharField(max_length=50) 
     address = models.CharField(max_length=80) 

     def __unicode__(self): 
      return u"%s the place" % self.name 

    class Restaurant(models.Model): 
     place = models.OneToOneField(Place, primary_key=True) 
     serves_hot_dogs = models.BooleanField() 
     serves_pizza = models.BooleanField() 

     def __unicode__(self): 
      return u"%s the restaurant" % self.place.name 

    # Create a couple of Places. 
    >>> p1 = Place(name='Demon Dogs', address='944 W. Fullerton') 
    >>> p1.save() 
    >>> p2 = Place(name='Ace Hardware', address='1013 N. Ashland') 
    >>> p2.save() 

    # Create a Restaurant. Pass the ID of the "parent" object as this object's ID. 
    >>> r = Restaurant(place=p1, serves_hot_dogs=True, serves_pizza=False) 
    >>> r.save() 

    # A Restaurant can access its place. 
    >>> r.place 
    <Place: Demon Dogs the place> 
    # A Place can access its restaurant, if available. 
    >>> p1.restaurant 

因此,在他们的示例中,他们只是简单地调用p1.restaurant而不明确定义该名称。 Django假设名称以小写开头。如果对象名称有多个单词,比如FancyRestaurant,会发生什么?

附注:我试图以这种方式扩展用户对象。这可能是问题吗?

回答

11

如果你定义了一个自定义related_name那么它将使用它,否则它将小写整个模型名称(在你的例子.fancyrestaurant)。看到别的块django.db.models.related code

def get_accessor_name(self): 
    # This method encapsulates the logic that decides what name to give an 
    # accessor descriptor that retrieves related many-to-one or 
    # many-to-many objects. It uses the lower-cased object_name + "_set", 
    # but this can be overridden with the "related_name" option. 
    if self.field.rel.multiple: 
     # If this is a symmetrical m2m relation on self, there is no reverse accessor. 
     if getattr(self.field.rel, 'symmetrical', False) and self.model == self.parent_model: 
      return None 
     return self.field.rel.related_name or (self.opts.object_name.lower() + '_set') 
    else: 
     return self.field.rel.related_name or (self.opts.object_name.lower()) 

而且这里是如何的OneToOneField calls it

class OneToOneField(ForeignKey): 
    ... snip ... 

    def contribute_to_related_class(self, cls, related): 
     setattr(cls, related.get_accessor_name(), 
       SingleRelatedObjectDescriptor(related)) 

的opts.object_name(在django.db.models.related.get_accessor_name引用)defaults to cls.__name__

至于

附注:我想延长 用户对象以这种方式。可能是 的问题?

不,它不会,User模型只是一个常规的django模型。只要小心related_name碰撞。