Search code examples
databasedjangogeneric-foreign-key

Django generic foreign key field not assigned during construction, but is able to be assigned post-construction


I am having an odd issue with Django generic foreign keys where the generic field will not stick if I assign it using the constructor. It will only stick post-construction. I cannot find any information on this, so I'm creating a new question on this. Any ideas why this is occurring?

Below is my class

class Answer(models.Model):
    question = models.OneToOneField(Question)
    date = models.DateField()

    # Generic relation to contain heterogeneous data of class *Data
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    answer_data = generic.GenericForeignKey('content_type', 'object_id')

    def __unicode__(self):
        question = ""
        if hasattr(self, 'question'):
            question = self.question.__unicode__()
        else:
            question = "Question undefined"

        answer = ""
        if hasattr(self, 'answer_data'):
            answer = self.answer_data.__unicode__()
        else:
            answer = "Answer undefined"

        return "Question: {" + question + "}; Answer: {" + answer + "}"

Here is my shell session which demonstrates the issue:

>>> from nequals1.models import *
>>> import datetime
>>> q = Question(text="Is this a question?")
>>> d = CharData(data="Yes, this is a question")
>>> a = Answer(question=q, date = datetime.datetime.now(), answer_data=d)
>>> a
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/Library/Python/2.7/site-packages/django/db/models/base.py", line 373, in __repr__
    u = unicode(self)
  File "/Users/kheck/PycharmProjects/neq1/nequals1/models.py", line 30, in __unicode__
    answer = self.answer_data.__unicode__()
AttributeError: 'NoneType' object has no attribute '__unicode__'
>>> a.answer_data=d
>>> a
<Answer: Question: {Is this a question?}; Answer: {Yes, this is a question}>

Solution

  • You haven't saved d (or any of the items, for that matter), so it has no id which can be used in the object_id field of the generic relation. Save it first before allocating it to a.