TheOne
TheOne

Reputation: 11159

django has more than 1 foreignkey error

My models file works just fine. As soon as I replace every models.Model with MyModel (a child-class of models.Model), one of my models raises a

<class 'puppy.cms.models.Appearance'> has more than 1 ForeignKey to <class 'puppy.cms.models.Segment'>

exception. The only thing that I am doing in the child class is override the clean method.

What could I be doing wrong?

class SansHashUrl(object):
    """ Upon each call to clean, iterates over every field,
    and deletes all '#/' and '#!/' occurances.
    IMPORTANT: This mixin must be listed first in the inheritance list to work
    properly. """

    def clean(self):

        attrs = (field.attname for field in self.__class__._meta.fields
                               if isinstance(field, models.CharField)
                               or isinstance(field, models.TextField))

        for attr in attrs:
            attr_value = self.__getattribute__(attr)
            tokens = attr_value.split()
            for i, token in enumerate(tokens):
                if has_internal_domain(token):
                    suggested_url = re.sub('#!?/','', token)
                    tokens[i] = suggested_url
            self.__setattr__(attr, ' '.join(tokens))

class MyModel(SansHashUrl, models.Model):
    pass 

Model that throws the error:

class Appearance(MyModel):

    appearance_type = models.CharField(max_length=20,
                                       choices=APPEARANCE_TYPE_CHOICES)
    person = models.ForeignKey(Person, related_name='person_appearance')
    item = models.ForeignKey(ManagedItem)

    class Meta:
        unique_together = (('person', 'item'),)

    def __unicode__(self):
        return self.person.__unicode__()

In reference to:

class Segment(Story, HasStatsTags, HasFullUrl):
...

It might be useful to note that Story is a subclass of ManagedItem (a subclass of MyModel).

Upvotes: 1

Views: 755

Answers (1)

Daniel Roseman
Daniel Roseman

Reputation: 599620

You need to declare MyModel (and probably ManagedItem) as an abstract model in its Meta class, otherwise Django will create a separate table for them and define FKs between them.

class MyModel(SansHashUrl, models.Model):
    class Meta:
        abstract = True

Upvotes: 4

Related Questions