views:

70

answers:

3

I have a models file that looks similar to the following:

class WithDate(models.Model):
    addedDate = models.DateTimeField(auto_now_add=True)
    modifiedDate = models.DateTimeField(auto_now=True)

    class Meta:
        abstract = True

class Match(WithDate):
    ...

class MatchFilter(django_filters.FilterSet):
    class Meta:
        model = Match

class Notify(WithDate):
    matchId = models.ForeignKey(Match)
    headline = models.CharField(null=True, blank=True, max_length=10)

For each Match I'm trying to get a count of notify records that have a headline. So my call looks like

matchObjs = Match.objects.annotate(notifies_made=Count('notify__headline__isnull'))

This keeps throwing a FieldError. I've simplified the query down to

matchObjs = Match.objects.annotate(notifies_made=Count('notify'))

And I still get the same FieldError... I've seen this work in other cases (other documentation, other SO questions like this one) but I can't figure out why I'm getting an error.

The specific error that is returned is as follows:

Cannot resolve keyword 'notify' into field. Choices are: (all fields from Match model)

Does anyone have a clue as to why I can't get this annotation to work across tables? I'm baffled after looking at the other SO question and various Django docs where I've seen this done.

Edit: I am using Django 1.1.1

Edit 2: I've tried renaming the matchId field to just match... and I've eliminated the WithDate class, adding in the addedDate and modifiedDate straight into the model class definitions. Neither of these changes got rid of the error message.

Edit 3: After reconstructing my models file piece by piece, I realized the inclusion of Alex Gaynor's django-filter plug-in was causing the problem. I didn't think this was relevant at first, but since it now is, I've included the Match FilterSet class that causes the error. When I remove the MatchFilter class, it works just fine. I'm trying to go through the django-filter code to figure out why this is happening, but if anyone else has an idea, I'd be very interested!

A: 

The default name for a reverse relation is modelname_set, so you should try:

matchObjs = Match.objects.annotate(notifies_made=Count('notify_set'))

or better, add a related name to the fields declaration, and then use the query you wrote:

matchId = models.ForeignKey(Match, related_name='notify')
Ofri Raviv
It's still giving me a FieldError: "Cannot resolve keyword 'notify_set' into field." error. Same goes for when I try adding the related_name parameter and using just 'notify'.
X_9
A: 

You're clearly effed.

A visitor
A: 

It seems that the problem was the MatchFilter was being defined before the Notify model in the models.py file. Once I rearranged the file to read as follows...

class WithDate(models.Model):
    addedDate = models.DateTimeField(auto_now_add=True)
    modifiedDate = models.DateTimeField(auto_now=True)

    class Meta:
        abstract = True

class Match(WithDate):
    ...

class Notify(WithDate):
    matchId = models.ForeignKey(Match)
    headline = models.CharField(null=True, blank=True, max_length=10)

class MatchFilter(django_filters.FilterSet):
    class Meta:
        model = Match

I was no longer getting the FieldError.

X_9