Django------(Related objects)相关对象查询

     When you define a relationship in a model(i.e.,a ForeignKey,OneToOneField,ManyToManyField),instance of that models will have a convenient API to access the related objects.

     Django creates API accessors for the "other" side of the relationship -- the link from the related model to the model that defines the relationship. For example, a Blog object b has access to a list of all related Entry objects via the entry_set attribute: b.entry_set.all().

    All examples in this section use the sample Blog, Author and Entry models defined at the previous Blog.

One-to-many relationships:
Faward:

>>> e = Entry.objects.get(pk=2)
>>> e.blog # Return the related Blog object.

Changes to the foreignkey are not saved to the database until you call save().

>>> e = Entry.objects.get(pk=6)
>>> e.blog = some_blog
>>> e.save()

If a foreign key field has null=True set, you can assign None to it:

>>> e = Entry.objects.get(id=2)
>>> e.blog = None
>>> e.save() # "UPDATE blog_entry SET blog_id = NULL ...;"
>>> e = Entry.objects.get(id=2)
>>> print e.blog  # Hits the database to retrieve the associated Blog.
>>> print e.blog  # Doesn't hit the database; uses cached version.
>>> e = Entry.objects.select_related().get(id=2)
>>> print e.blog  # Doesn't hit the database; uses cached version.
>>> print e.blog  # Doesn't hit the database; uses cached version.

backward:

>>> b = Blog.objects.get(id=1)
>>> b.entry_set.all() # Returns all Entry objects related to Blog.

# b.entry_set is a Manager that returns QuerySets.
>>> b.entry_set.filter(headline__contains='Lennon')
>>> b.entry_set.count()

You can override the FOO_set name by setting the related_name parameter in the ForeignKey() definition. For example, if the Entry model was altered to blog=models.ForeignKey(Blog, related_name='entries'),the code would look like this:

>>> b = Blog.objects.get(id=1)
>>> b.entries.all()
>>> b.entries.filter(headline__contains='Lennon')
>>> b.entries.count()

You cannot access a reverse ForeignKey Manager from the class; it must be accessed from an instance:

>>> Blog.entry_set
Traceback:
    ...
AttributeError: "Manager must be accessed via instance".
add(.......)
>>> b = Blog.objects.get(id=1)
>>> e = Entry.objects.get(id=234)
>>> b.entry_set.add(e) # Associates Entry e with Blog b.
>>> b = Blog.objects.get(id=1)
>>> e = b.entry_set.create(
...     headline='Hello',
...     body_text='Hi',
...     pub_date=datetime.date(2005, 1, 1)
... )

# No need to call e.save() at this point -- it's already been saved.
>>> b = Blog.objects.get(id=1)
>>> e = Entry.objects.get(id=234)
>>> b.entry_set.remove(e) # Disassociates Entry e from Blog b.

In order to prevent database inconsistency, this method only exists on ForeignKey objects where null=True. I
>>> b = Blog.objects.get(id=1)
>>> b.entry_set.clear()

Just like remove(), clear() is only available on ForeignKeys where null=True.

Many-to-many relationships:

e = Entry.objects.get(id=3)
e.authors.all() # Returns all Author objects for this Entry.
e.authors.count()
e.authors.filter(name__contains='John')

a = Author.objects.get(id=5)
a.entry_set.all() # Returns all Entry objects for this Author.

One-to-one relationships:

class EntryDetail(models.Model):
    entry = models.OneToOneField(Entry)
    details = models.TextField()

ed = EntryDetail.objects.get(id=2)
ed.entry # Returns the related Entry object.
e = Entry.objects.get(id=2)
e.entrydetail # returns the related EntryDetail object
e.entrydetail = ed

反向关系怎么成为可能?

其他的对象关系映射都要求在两边都定义关系,但是Django的开发者认为这违反的DRY的原则,所以django只要求在一方定义关系,但是怎么让它成为可能呢,主要是在INSTALL_APP里。

If you have a Blog object b with id=5, the following three queries would be identical(相同的):

Entry.objects.filter(blog=b) # Query using object instance
Entry.objects.filter(blog=b.id) # Query using id from instance
Entry.objects.filter(blog=5) # Query using id directly
posted @ 2012-10-24 11:36  事件轮询,回不到过去  阅读(464)  评论(0编辑  收藏  举报