Hi all,
I have two models:
class Visitor(models.Model):
name =
...
class VirtualVisitor(Visitor):
type =
...
class Product(models.Model):
# Generic Relation
visitor_content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE, default=None, null=True, blank=True, limit_choices_to={
'model__in': ('visitor', 'virtualvisitor',)})
visitor_object_id = models.PositiveIntegerField(default=None, null=True, blank=True)
visitor = GenericForeignKey('visitor_content_type', 'visitor_object_id')
However, when creating Product objects in the admin, the visitor filed is not shown at all.
How can I enable it? I would like to have a dropbox with a list of all visitor/virtualvisitor objects.
Hm, I was wrong, the relation is there in admin, but its not noticeable.
It is split into two widgets, Visitor content type, which allows you to select the model,
and Visitor object id, which expects an integer.
Is there a away to replace it with a dropdown list, as the plain foreign key has?
By default, no. But I suspect that you could create a custom widget to do that for you, along with defining a new field in the form for this that isn’t a field in the model.
I could see handling this by creating a custom value
attribute for the select list. You could create the values as something like a 2-tuple of (Model, pk)
, and interpret that in the to_python
method of your form field to set the two component fields of the model.
See the docs for Generic Relations for some of the other limitations along these lines when trying to use GFKs.
To say the truth, I realised that GFKs are not well supported, so I replace it with another implementation, using a proxy class.
I limited the objects in each class based on the type, and hide some fields in forms. Its better supported in django I think.
George
<opinion>
GFKs in general are an anti-pattern, truly useful in far fewer situations than many people believe. (In that sense, I put them in the same category as Django signals.)
I believe they’re supported well-enough, for what they’re supposed to do.
</opinion>
For more on this, see: