#2297 closed defect (invalid)
ForeignKey and *_set accessor method broke
Reported by: | Owned by: | Adrian Holovaty | |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | |
Severity: | normal | Keywords: | ForeignKey _set |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
I revved to v3278 and my app broke. In my view I adjust some fields of the model.
My model looks something like this
class Foo(models.Model): name = models.CharField(maxlength=30) class Bar(model.Model): foo = models.ForeignKey(Foo) data = models.CharField(maxlength=30)
later on I iterate over my bars and try and get my foos from them. ie
for foo in bar.foo_set.all(): #do something with foo
I now get an attribute error when trying to do this:
AttributeError at /fooapp/ 'Bar' object has no attribute 'foo_set' Request Method: GET Request URL: http://localhost:8000/fooapp/ Exception Type: AttributeError Exception Value: 'Bar' object has no attribute 'foo_set'
Just wondering if there was a change that broke then _set functionality recently
I apologize for how vague this is. I have another model that has a foreign key and code similar to the above still works with that. I've briefly diffed the sources didn't chance on anything that looked to cause this change....
Change History (5)
comment:1 by , 18 years ago
Resolution: | → invalid |
---|---|
Status: | new → closed |
comment:2 by , 18 years ago
Stupid not logged in status. That was me in the last comment, for the record.
comment:3 by , 18 years ago
And just to clarify it conceptually, this goes back to foreign keys being a one-to-many relationship. To take an example from the official tutorial, you have Polls and Choices. A Choice only ever belongs to one Poll, so you access that as choice.poll
. But a Poll has many Choices, so you access them via poll.choice_set
.
comment:4 by , 18 years ago
Resolution: | invalid |
---|---|
Status: | closed → reopened |
I'm sorry, I messed up my foos and bars. Let me try again. (Not using
foo nor bar). Yes, that example was wrong, but here's a simpler version of the code that is failing. (Yes I've read the tutorial)
I have a Component object, a Version object and a Data object (that
holds additional data about the version object). They look like
this::
class Component(models.Model): name = models.CharField(maxlenth=30) ... class Version(models.Model): component = models.ForeignKey(Component) version = models.CharField(maxlength=30) ... class Data(models.Model): meta_data = models.CharField(maxlength=30) version = models.ForeignKey(Version)
Now given a component, I want to get all the version instances and
alll the data associated with it. So I do something like this:
for version in component_instance.version_set.all(): for data in version.data_set.all(): #adjust meta_data on data
Here's the error
AttributeError at /myapp/ 'Version' object has no attribute 'data_set' Request Method: GET Request URL: http://localhost:8000/myapp/ Exception Type: AttributeError Exception Value: 'Version' object has no attribute 'data_set' Exception Location: /home/matt/.views.py in _add_metadata, line 293
So this is the weird thing. Accessing _set.all() works on the
component_instance, but fails on the next line... Is _set.all() no
longer returning instances? Again, this worked before updating svn.
comment:5 by , 18 years ago
Resolution: | → invalid |
---|---|
Status: | reopened → closed |
I'm closing this since I appear to be a complete idiot. I guess I had a typo somewhere, which I somehow fixed and somehow now it's working...
Sorry for barking up the wrong tree...
OK, this is going to sound confusing, because you are overloading the "foo" and "bar" words way more than can be healthy, but here goes...
foo_set
refers to the reverse side of the relation fromFoo
back toBar
. If you want to refer to the relation in aBar
object, just usebar.foo
, it's a simple attribute. If you want to iterate over all the things that refer to a particularFoo
-- call him fred -- thenAll documented here: http://www.djangoproject.com/documentation/db_api/#backward