2010-09-13 11 views
5

Oprócz jednego przykładu w dokumentach, nie mogę znaleźć żadnej dokumentacji na temat tego, jak dokładnie django wybiera nazwę, z której można uzyskać dostęp do obiektu potomnego z obiektu nadrzędnego. W ich przykład, wykonaj następujące czynności:W jaki sposób django relacje jeden-do-jednego mapuje nazwę do obiektu podrzędnego?

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 

więc w ich przykład, po prostu zadzwoń p1.restaurant bez wyraźnego zdefiniowania tej nazwy. Django zakłada, że ​​nazwa zaczyna się od małej litery. Co się stanie, jeśli nazwa obiektu zawiera więcej niż jedno słowo, np. FancyRestaurant?

Uwaga boczna: Próbuję w ten sposób przedłużyć obiekt użytkownika. Czy to może być problem?

Odpowiedz

11

Jeśli zdefiniujesz niestandardowy related_name, użyjesz go, w przeciwnym razie będzie on zawierał całą nazwę modelu (w twoim przykładzie .fancyrestaurant). Zobacz blok innego w 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()) 

A oto jak 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 (wymieniony w django.db.models.related.get_accessor_name) defaults to cls.__name__.

chodzi o

marginesie: Próbuję rozszerzyć przedmiot użytkownika w ten sposób. Czy to może być problem z ?

Nie, nie będzie, model User jest zwykłym modelem django. Po prostu uważaj na kolizje related_name.

Powiązane problemy