11

I have the following model:

class A(models.Model):
    name = models.CharField(max_length=50)
    content_type = models.ForeignKey(ContentType)

This model is supposed to be the root model in some inheritance tree and content_type attribute is a kind of a hint about what type is really stored. Obviously, I should calculate content_type transparently upon A instance creation. I think, in __init__. But there is a problem - there are two main contexts in which A instances are created:

  1. a = A(name='asdfdf') # here we must fill in content_type
  2. by QuerySet machinery with *args tuple. In this case I shouldn't fill in content_type

So, I'm trying to write:

def __init__(self, *args, **kwargs):
    super(A, self).__init__(*args, **kwargs)
    if self.content_type is None: # << here is the problem
        self.content_type = ContentType.objects.get_for_model(self)

The thing is self.content_type is ReverseSingleRelatedObjectDescriptor instance with __get__ overriden so that it throws in case value is not set. Yes, I can do following:

def __init__(self, *args, **kwargs):
    super(A, self).__init__(*args, **kwargs)
    try: 
        self.content_type
    except Exception, v:
        self.content_type = ContentType.objects.get_for_model(self)

But I don't like it. Is there a more 'polite' way to check if the ForeignKey attribute is set?

Dominic Rodger
  • 97,747
  • 36
  • 197
  • 212
Andrew V.
  • 113
  • 1
  • 1
  • 4
  • Firstly, if you want `content_type` to be optional, I think you'll need to set `blank = True, null = True` on your field definition. – Dominic Rodger Jan 05 '10 at 09:57
  • 1
    I don't want it to be optional, I just don't want to set its value if it has already been set by Django (in the process of reading from DB). – Andrew V. Jan 05 '10 at 10:56

1 Answers1

30

Does it work if you examine self.content_type_id instead of self.content_type?

Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895