13👍
Well, looking at the question in Chris’s comment helped, and I wrote a mixin to return the object using a quick lookup (which should be cached):
class ContactMixin(object):
@property
def contactcard(self):
ctype = ContentType.objects.get_for_model(self.__class__)
try:
contact = Contact.objects.get(content_type__pk = ctype.id, object_id=self.id)
except Contact.DoesNotExist:
return None
return contact
and the Person:
class Person(ContactMixin, models.Model):
...
now I can just call
myperson.contactcard.phone_number
I won’t accept just yet, as there might be other suggestions
5👍
if a queryset contains exactly one element you can do qs.get()
, or in your case
person.contact.get()
(you may still need to catch the DoesNotExists
exception)
- Overriding Size of Django Admin Multi-select Widget
- Django select_related on chained foreign keys
- Run django app via nginx+uwsgi in a subpath
- Django South Error: AttributeError: 'DateTimeField' object has no attribute 'model'`
- Django – How to show messages under ajax function
4👍
The accepted answer above implicitly assumes that the contact field is nullable whereas in the original post this is not the case. Assuming that you do want the key to be nullable I would do this:
class Contact(models.Model):
...
content_type = models.ForeignKey(
ContentType,
blank=True,
null=True,
on_delete=models.SET_NULL
)
object_id = models.PositiveIntegerField(blank=True, null=True)
content_object = GenericForeignKey('content_type', 'object_id')
class Meta:
unique_together = ('content_type', 'object_id',)
class Person(models.Model):
...
contacts = generic.GenericRelation(Contact)
@property
def contact(self):
return self.contacts.first()
# Or if you want to generalise the same thing to a mixin.
class ContactableModel(models.Model):
contacts = generic.GenericRelation(Contact)
class Meta:
abstract = True
@property
def contact(self):
return self.contacts.first()
If there is no contact then .first()
will return None
. Simple and pythonic. There’s no need for all the generic introspection mechanics of the accepted answer, the references are already right at our fingertips.
- Import m2m relation in django-import-export
- Django CORS Access-Control-Allow-Origin missing
- {% load static %} and {% load staticfiles %}: which is preferred?
- Unable to install MySQL-python
- Django finds tests but fail to import them