0

I've read in the docs and stackoverflow but i cant figure out why my foreign key following isnt working, django just says that there is no such attribute as vote_story_set.all().

I have a table named story and one named vote_story and the story table has several foreign keys like a foreign to vote_story to get the number of votes for a news story.

According to the docs and the detailed answer here: *_set attributes on Django Models i created an object like this:

all_stories = Story.objects.all()
votes = all_stories.vote_story_set.all()

but this doesnt work since django says that there is no such attribute as "vote_story_set". The database table for story has the 'votes' attribute as a foreign key to the table Votes_story. From the examples ive seen this should be working so i dont understand why it doesnt. There is no foreign keys in the Votes_story table, just a primay key and the attribute 'votes' containing the number of votes.

Update: Models and template is shown below for Story and Vote_story as well as the relevant view.

Models:

class Story(models.Model):
    story_id = models.IntegerField(primary_key=True)
    date_added = models.DateTimeField(auto_now_add=True)
    date_modified = models.DateTimeField(auto_now=True)
    title = models.CharField(max_length=150)
    description = models.CharField(blank=True, null=True, max_length=2000)
    story_text = models.TextField()
    picture = models.ImageField(blank=True, null=True, upload_to="story/images")
    storyAccessLevelID = models.ForeignKey(StoryAccessLevel)
    categoryID = models.ForeignKey(Category)
    votes = models.ForeignKey(Vote_story, blank=True, null=True)
    comments = models.ForeignKey(Comment, blank=True, null=True)

   def __unicode__(self):
        return self.title

class Vote_story(models.Model):
    votes = models.IntegerField()

    def __unicode__(self):
        return self.votes

In the file Vote_story is defined above Story so it can find it. In Vote_story i let django create the primary key automatically unlike Story. There is currently one vote for one of the stories added.

Template code (the relevant portion):

<table class="table table-hover">
    <thead>
        <tr>
            <th>Title</th>
            <th>Description</th>
            <th>Date added</th>
            <th>Votes</th>
            <th>Comments</th>
        </tr>
    </thead>
    <tbody>
        {% for story in all_stories %}
        <tr>
            <td><a href="/story/details/{{ story.story_id }}">{{ story.title }}</a></td>
            <td>{{ story.description }}</td>
            <td>{{ story.date_added }}</td>
            <td>{{ story.votes }}</td>
            <td>{{ story.comments }}</td>
        </tr>
        {% endfor %}
    </tbody>
</table>

The view is like this:

def list_all_stories(request):
    """ Show all stories """
    all_stories = Story.objects.all()
    return render(request, "base/story/all_stories.html", {'all_stories': all_stories})
Community
  • 1
  • 1

1 Answers1

2

all_stories is a queryset, not an instance. vote_story_set is an attribute on each instance within the queryset, not the queryset itself.

Plus, you seem to be confused about the direction of relations. If your ForeignKey goes from Vote to VoteStory, you don't need the reverse relation, you need the forward one, which is just whatever you called the field. Again, though, this is an attribute of each instance, not the queryset.

Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
  • ah, ok. i sent the queryset to the template and used a for loop to iterate over it and used story.vote_story_set.all() but it still doesnt work, and now im using the attribute on an instance of the queryset. The error message im getting is "Could not parse the remainder: '()' from 'story.vote_story_set.all()' ...the foreign key is going from the Story table to the Vote_story table. If im using the field directly i just get a string that says "None" on the page even though there are values in the table –  Feb 23 '14 at 21:12
  • 1
    You seriously need to do the tutorial. All this is fully explained there. The tutorial explains, among other things, that you don't use parentheses to call methods in templates, which is the cause of that error. But also you still didn't read the second part of my answer: you are following that relationship *forward*, not backward, so you don't need _set, you just need whatever the FK field is called. That, too, is explained in the tutorial. – Daniel Roseman Feb 23 '14 at 21:15
  • Hmm, ok, i have read the tutorial, but its a while ago now since ive been reading about a lot of other topics as well.. will definitely take another looks. thanks for taking your time to reply. –  Feb 23 '14 at 22:24
  • I read about how _set works again as well as in the related object reference and i get it, you use _set when you are in the other table that the foreign key is pointing to if you need to reference the table the foreign key is defined in.. so i would do what you said, just use the attribute directly..but when specifying story.votes_id i only get "None" displayed even though i have a unicode method..the vote_story table does have a value in it so it shouldnt be a problem should it? –  Feb 24 '14 at 20:10
  • You should probably post your models, and the updated template. – Daniel Roseman Feb 24 '14 at 20:18
  • I have now updated my original post to include the models, template and view –  Feb 24 '14 at 20:38
  • i fixed the problem, i have entered the test data the wrong way. thanks for your help about the set functionality –  Feb 25 '14 at 20:12