class Child(models.Model):
object_id = PositiveIntegerField()
content_type = ForeignKey(ContentType)
content_object = GenericForeignKey()
class GenericMixin(models.Model):
relation = GenrericRelation(Child, related_query_name='%(class)s')
class Meta:
abstract = True
class Parent(GenericMixin):
name = CharField()
instance = Child.objects.filter(parents__name) # This query will not
work, as 'parents' is not set as the related_query_name for the Parent
Model
}}}
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/25354>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
* needs_better_patch: => 0
* needs_tests: => 0
* needs_docs: => 0
* stage: Unreviewed => Accepted
Old description:
> It currently isn't possible to set related_query_name on a field on an
> abstract base class using the "%(class)s" or "%(app_label)s" string
> formatting syntax that is allowed for the related_name parameter of
> field. This is particularly problematic when trying to define an abstract
> base class that uses a GenericRelation, since you can't specify a
> related_name, but can specify a related_query_name.
> For Example:
> {{{
> #!div style="font-size: 80%"
> Code highlighting:
> {{{#!python
>
> class Child(models.Model):
> object_id = PositiveIntegerField()
> content_type = ForeignKey(ContentType)
> content_object = GenericForeignKey()
>
> class GenericMixin(models.Model):
> relation = GenrericRelation(Child, related_query_name='%(class)s')
>
> class Meta:
> abstract = True
>
> class Parent(GenericMixin):
> name = CharField()
>
> instance = Child.objects.filter(parents__name) # This query will not
> work, as 'parents' is not set as the related_query_name for the Parent
> Model
> }}}
> }}}
New description:
It currently isn't possible to set related_query_name on a field on an
abstract base class using the "%(class)s" or "%(app_label)s" string
formatting syntax that is allowed for the related_name parameter of field.
This is particularly problematic when trying to define an abstract base
class that uses a GenericRelation, since you can't specify a related_name,
but can specify a related_query_name. For Example:
{{{#!python
from django.contrib.contenttypes.fields import GenericForeignKey,
GenericRelation
from django.contrib.contenttypes.models import ContentType
from django.db import models
class Child(models.Model):
object_id = models.PositiveIntegerField()
content_type = models.ForeignKey(ContentType)
content_object = GenericForeignKey()
class GenericMixin(models.Model):
relation = GenericRelation(Child, related_query_name='%(class)s')
class Meta:
abstract = True
class Parent(GenericMixin):
name = models.CharField(max_length=100)
>>> from app.models import Child
>>> Child.objects.filter(parents__name='foo')
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/home/tim/code/django/django/db/models/manager.py", line 122, in
manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/home/tim/code/django/django/db/models/query.py", line 788, in
filter
return self._filter_or_exclude(False, *args, **kwargs)
File "/home/tim/code/django/django/db/models/query.py", line 806, in
_filter_or_exclude
clone.query.add_q(Q(*args, **kwargs))
File "/home/tim/code/django/django/db/models/sql/query.py", line 1240,
in add_q
clause, _ = self._add_q(q_object, self.used_aliases)
File "/home/tim/code/django/django/db/models/sql/query.py", line 1266,
in _add_q
allow_joins=allow_joins, split_subq=split_subq,
File "/home/tim/code/django/django/db/models/sql/query.py", line 1149,
in build_filter
lookups, parts, reffed_expression = self.solve_lookup_type(arg)
File "/home/tim/code/django/django/db/models/sql/query.py", line 1035,
in solve_lookup_type
_, field, _, lookup_parts = self.names_to_path(lookup_splitted,
self.get_meta())
File "/home/tim/code/django/django/db/models/sql/query.py", line 1327,
in names_to_path
"Choices are: %s" % (name, ", ".join(available)))
django.core.exceptions.FieldError: Cannot resolve keyword 'parents' into
field. Choices are: %(class)s, content_object, content_type,
content_type_id, id, object_id
}}}
--
Comment:
Here's the
[https://github.com/django/django/blob/1bbca7961cee20c4ddd453a7d74d316e84f4bbb5/django/db/models/fields/related.py#L295-L298
implementation for related_name]. I haven't investigated, but it seems it
may be reasonable to add this.
--
Ticket URL: <https://code.djangoproject.com/ticket/25354#comment:1>
Comment (by jpulec):
I'd be happy to take a crack at it, but I've never contributed before, and
am not the most familiar with the 'related' internals of django. Is this
something that should get brought up on django-developers, or would
starting to work on a patch be the right approach?
--
Ticket URL: <https://code.djangoproject.com/ticket/25354#comment:2>
Comment (by charettes):
@jpulec, I don't think this needs to be brought up on django-developers.
You can go ahead and work on a patch and publish it as PR on Github. See
our [https://docs.djangoproject.com/en/dev/internals/contributing/
contributing guidelines].
From what I can see of the actual implementation of `related_name` linked
above by Tim a simple similar `if self.remove_field.related_query_name`
block should do. Feel free to hop on #django-dev and ping `charettes` if
you need further help.
--
Ticket URL: <https://code.djangoproject.com/ticket/25354#comment:3>
* status: new => assigned
* owner: nobody => jpulec
--
Ticket URL: <https://code.djangoproject.com/ticket/25354#comment:4>
Comment (by jpulec):
[https://github.com/django/django/pull/5886 PR]
--
Ticket URL: <https://code.djangoproject.com/ticket/25354#comment:5>
* has_patch: 0 => 1
Comment:
Please don't forget to check "Has patch" so the ticket appears in the
review queue.
--
Ticket URL: <https://code.djangoproject.com/ticket/25354#comment:6>
* needs_better_patch: 0 => 1
Comment:
Left some comments for improvement on the pull request. Please uncheck
"Patch needs improvement" when you update it.
--
Ticket URL: <https://code.djangoproject.com/ticket/25354#comment:7>
* needs_better_patch: 1 => 0
--
Ticket URL: <https://code.djangoproject.com/ticket/25354#comment:8>
* status: assigned => closed
* resolution: => fixed
Comment:
In [changeset:"f05722a08a11b2e6c6c9acdf2bacd6a6128ccbb0" f05722a0]:
{{{
#!CommitTicketReference repository=""
revision="f05722a08a11b2e6c6c9acdf2bacd6a6128ccbb0"
Fixed #25354 -- Added class/app_label interpolation for
related_query_name.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/25354#comment:9>