Opened 18 years ago
Closed 4 years ago
#2316 closed Bug (duplicate)
GenericRelation and get_or_create do not work together
Reported by: | Rudolph Froger | Owned by: | Adrian Holovaty |
---|---|---|---|
Component: | contrib.contenttypes | Version: | dev |
Severity: | Normal | Keywords: | GenericRelation |
Cc: | jonozzz | Triage Stage: | Accepted |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
I think GenericRelation and get_or_create do not work together. Example:
baz = Bar.objects.get_or_create(content_object=foo)
You get an exception:
Cannot resolve keyword 'content_object' into field
Attachments (3)
Change History (26)
comment:3 by , 18 years ago
Component: | Admin interface → Core framework |
---|---|
Has patch: | set |
Keywords: | GenericRelation added |
Needs tests: | set |
Resolution: | → fixed |
Status: | new → closed |
I created a simple patch for this. It seems to work for me.
by , 18 years ago
Attachment: | generic_patch.diff added |
---|
patch to fix get_or_create with GenericRelation
by , 18 years ago
Attachment: | generic_patch.2.diff added |
---|
other patch had problems, this one works better
comment:4 by , 18 years ago
Triage Stage: | Unreviewed → Accepted |
---|
comment:5 by , 17 years ago
Resolution: | fixed |
---|---|
Status: | closed → reopened |
This was never fixed (slevcom1: posting a working patch is fine, but until it's in svn the ticket stays open)
Check out #3121 for a related ticket.
comment:6 by , 17 years ago
Resolution: | → duplicate |
---|---|
Status: | reopened → closed |
In fact, I just tried #3121 and that works fine. So I'll close this as a dupe.
comment:7 by , 15 years ago
Resolution: | duplicate |
---|---|
Status: | closed → reopened |
Version: | SVN → 1.1 |
This bug is neither a duplicate nor has it been fixed. Using Django 1.1.1, the issue still persists, as demonstrated by:
# Model definition for app ticket2316 demonstrating bug #2316 from django.db import models from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes import generic class SomeObject(models.Model): test_content_type = models.ForeignKey(ContentType, null=True, blank=True) test_object_id = models.PositiveIntegerField(null=True, blank=True) test_object = generic.GenericForeignKey('test_content_type', 'test_object_id')
After the customary syncdb, etc:
>>> from ticket2316.models import SomeObject >>> from django.contrib.auth.models import User >>> User.objects.all()[0] <User: wam> >>> user = _ >>> SomeObject(test_object=user) <SomeObject: SomeObject object> >>> SomeObject.objects.get_or_create(test_object=user) ------------------------------------------------------------ Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/home/wam/projs/virtualenvs/demo/lib/python2.6/site-packages/Django-1.1.1-py2.6.egg/django/db/models/manager.py", line 123, in get_or_create return self.get_query_set().get_or_create(**kwargs) File "/home/wam/projs/virtualenvs/demo/lib/python2.6/site-packages/Django-1.1.1-py2.6.egg/django/db/models/query.py", line 328, in get_or_create return self.get(**kwargs), False File "/home/wam/projs/virtualenvs/demo/lib/python2.6/site-packages/Django-1.1.1-py2.6.egg/django/db/models/query.py", line 299, in get clone = self.filter(*args, **kwargs) File "/home/wam/projs/virtualenvs/demo/lib/python2.6/site-packages/Django-1.1.1-py2.6.egg/django/db/models/query.py", line 498, in filter return self._filter_or_exclude(False, *args, **kwargs) File "/home/wam/projs/virtualenvs/demo/lib/python2.6/site-packages/Django-1.1.1-py2.6.egg/django/db/models/query.py", line 516, in _filter_or_exclude clone.query.add_q(Q(*args, **kwargs)) File "/home/wam/projs/virtualenvs/demo/lib/python2.6/site-packages/Django-1.1.1-py2.6.egg/django/db/models/sql/query.py", line 1675, in add_q can_reuse=used_aliases) File "/home/wam/projs/virtualenvs/demo/lib/python2.6/site-packages/Django-1.1.1-py2.6.egg/django/db/models/sql/query.py", line 1569, in add_filter negate=negate, process_extras=process_extras) File "/home/wam/projs/virtualenvs/demo/lib/python2.6/site-packages/Django-1.1.1-py2.6.egg/django/db/models/sql/query.py", line 1737, in setup_joins "Choices are: %s" % (name, ", ".join(names))) <class 'django.core.exceptions.FieldError'>: Cannot resolve keyword 'test_object' into field. Choices are: id, test_content_type, test_object_id
I'll try and work up a more formal unittest in the near future.
P.S. I don't exactly know how I should change the properties, considering this ticket has remained dormant for the past two years. I considered filing a new ticket, but the problem is *exactly* the failure condition this ticket was originally opened to address, it just appears the ticket got diverted onto a tangent with a similar, but not identical ticket that the original poster may have been experiencing as well.
comment:8 by , 15 years ago
Cc: | added |
---|
follow-up: 10 comment:9 by , 15 years ago
milestone: | → 1.3 |
---|---|
Version: | 1.1 → 1.2 |
Looks like this one missed another milestone, 1.2 is out and this totally legit patch didn't make it through.
Is anyone going to submit it into the SVN ?
comment:10 by , 15 years ago
Replying to jonozzz:
Note it's not necessary to change version to a higher number when releases go out. The version field is supposed to reflect what version of code was in use when the problem was reported (or the feature requested). When accurate, it gives a clue of how old the reported behavior is; updating it to be a higher number is rarely correct. It is not a target release for fixing the problem/implementing the feature: that's what milestone is for.
comment:11 by , 15 years ago
Component: | Core framework → Contrib apps |
---|
by , 14 years ago
Attachment: | 0001-Fixed-2316-Added-get_or_create-to-GenericRelatedObje.diff added |
---|
Updated patch with tests
comment:12 by , 14 years ago
Needs tests: | unset |
---|
Just updated the patch to the current state of the ORM and added some tests.
comment:13 by , 14 years ago
Has patch: | unset |
---|
The attached patch does not address the original problem, as can be seen if you change this line in the added test:
fatty = TaggedItem.objects.create(content_object=bacon, tag="fatty")
to:
fatty = TaggedItem.objects.get_or_create(content_object=bacon, tag="fatty")
The patch fixes a related problem, which is probably worthy of fixing on its own, although the original bug title would cover both cases.
The original bug would probably require patching core, or we might want to wait until core has support for virtual/composite fields and GenericRelations
could be re-worked to use that support.
So, the most recent patch needs to be put into a new ticket if it is to be included on its own. So I'm marking *this* ticket as having no patch.
Sorry for the ticket-churn, but it's needed to keep things sane. Thanks.
comment:14 by , 14 years ago
Component: | Contrib apps → contrib.contenttypes |
---|
comment:15 by , 14 years ago
Type: | defect → Bug |
---|
comment:16 by , 14 years ago
Severity: | normal → Normal |
---|
comment:13 by , 12 years ago
Status: | reopened → new |
---|
comment:15 by , 9 years ago
Version: | 1.2 → master |
---|
comment:16 by , 4 years ago
Resolution: | → duplicate |
---|---|
Status: | new → closed |
Fixed in ed37f7e979186c99a6f351c289eb486461601d80.
Duplicate of #23611.
If I see this right this does not work with any operation (get, filter, exclude, ...) and is so far not intended to be used this way.
(I think this bug targets models.GenericForeignKey, as there is no code-example provided)
Ugly workaround (thats the reason I posted in the first place ;-):
from django.contrib.contenttypes.models import ContentType
baz = Bar.objects.get_or_create(content_type=ContentType.objects.get_for_model(foo.class), object_id=getattr(foo, foo.class._meta.pk.column))
Somehow nicer (but unflexible in this form):
def do_generic_stuff(func, obj):
# call:
baz = do_generic_stuff(Bar.objects.get_or_create, foo)