user3595632 user3595632 - 5 months ago 7
Python Question

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

Answer

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 %}