user3595632
user3595632

Reputation: 5730

Foreignkey doesn't work in django

I'm using django 1.9.7 & python3.5 and have some problems in using Foreignkey.

models.py

from django.db import models


def enum(*sequential, **named):
    enums = dict(zip(sequential, range(len(sequential))), **named)
    reverse = dict((value, key) for key, value in enums.items())
    enums['reverse_mapping'] = reverse
    return type('Enum', (), enums)

Status_enum = enum('WAITING', 'DOWNLOADING', 'COMPLETE')


class Status(models.Model):
    cur_status = models.PositiveSmallIntegerField(blank=True, null=True, default=Status_enum.WAITING)

    def __str__(self):
        return Status_enum.reverse_mapping[self.cur_status]

class Source(models.Model):
    site_name = models.CharField(max_length=50, blank=True)
    site_url = models.CharField(max_length=100, blank=True)

    def __str__(self):
        return self.site_name

class Chart(models.Model):
    title = models.CharField(max_length=50)
    singer = models.CharField(max_length=50)
    youtube_url = models.CharField(max_length=100, blank=True)
    source  = models.ForeignKey(Source, null=True, blank=True)
    status = models.ForeignKey(Status, null=True, blank=True)
    download_date = models.DateField(blank=True, null=True)

    def __str__(self):
        return '{} - {} {}'.format(self.title, self.singer, self.status)

view.py

from django.shortcuts import render
from django.core.urlresolvers import reverse
from django.http import HttpResponse, HttpResponseRedirect

from .models import *


def music_list(request):
    status = Status.objects.filter(cur_status=Status_enum.WAITING)
    print(status[0].chart_set.all())
    return render(request, 'music/music_list.html', {'status':status})

def add_chart(request):
    return render(request, 'music/add_chart.html', {})


def site_chart(request, site_name):
    response = site_name + " Chart list"
    return HttpResponse(response)

def save_chart(request):
    title = request.POST['title']
    singer = request.POST['singer']
    status = Status.objects.get_or_create(cur_status=Status_enum.WAITING)
    chart = Chart(title=title, singer=singer, status=status[0])
    status[0].chart_set.add(chart, bulk=False)

    print(status[0].chart_set.all())

    return HttpResponseRedirect(reverse('music:music_list'))

In views.py, print(status[0].chart_set.all()) in music_list() and save_chart() works. It shows all charts associated with that status like belows:

[<Chart: Sorry - Justin Biber  WAITING>, <Chart: I want it that way - BSB WAITING>, <Chart: Sugar - Maroon5 WAITING>]

But when I pass it to 'music/music_list.html', it doesn't show any charts. This is my music_list.html.

<p> HI </p>
<p> {{status}} </p>
{% if status.chart_set.all %}
    AAAAAA
{% else %}
    BBB
{% endif %}
{% for chart in status.chart_set.all %}
    <p>{{ chart }}</p>
{% endfor %}

And the result page is,

enter image description here

I want to know why it doesn't show any charts only in html file. Thanks

Upvotes: 1

Views: 69

Answers (1)

solarissmoke
solarissmoke

Reputation: 31504

The status context variable is not a single Status object, but a list of objects returned by the filter query (in this case it contains only one item). You either need to loop through the list:

{% for s in status %}
    {% for chart in s.chart_set.all %}
        <p>{{ chart }}</p>
    {% endfor %}
{% endfor %}

or explicitly select the first item, the same way you are doing in the print statement in your view function:

{% for chart in status.0.chart_set.all %}
    <p>{{ chart }}</p>
{% endfor %}

Upvotes: 1

Related Questions