how to link pages depending on foreign key using django

Viewed 30

I tried to link countries to continents depending on the foreign key "ckey". I tried using filter and .raw but it didn't work. I tried to use it directly on HTML but it said it cannot praise it. I need to know if there is another way of linking pages like "continents -> countries -> cities -> ...." using Django.

models

from django.db import models

# Create your models here.
class Continents(models.Model):
    ckey = models.CharField(max_length=10, primary_key=True)
    continentName = models.CharField(max_length=50)

class country(models.Model):
    countryNum = models.IntegerField(primary_key=True)
    countryName = models.CharField(max_length=15)
    countryBrief= models.TextField(max_length=500)
    currency = models.CharField(max_length=15)
    cost = models.FloatField(max_length=10)
    cultures = models.TextField(max_length=300)
    rulesBrief = models.TextField(max_length=200)
    location = models.TextField(max_length=500)
    ckey = models.ForeignKey('Continents', on_delete=models.PROTECT)

views.py

from django.shortcuts import render
from django.http import HttpResponse
from .models import Continents, country

# Create your views here.
def home(request):
    return render(request,"guide/home.html")

def continents(request):
    continentdata = Continents.objects.all()
    return render(request,"guide/Continents.html",{'Continents':continentdata})

def countrylist(request):
    countries = country.objects.all()
    first_person = country.objects.filter(ckey='as45914')
    context = {
        "first_person":first_person,
        "countries":countries,
    }
    return render(request,"guide/countrylist.html",context=context)

html code

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    {{first_person}}
</body>
</html>

strange message I got when I run the code

How do I link pages like that? For example "Europe > United kingdom > all cities under UK London ..." using Django. I know how to do it in general, all countries > all cities, but not in that way.

2 Answers
# Get list by Obj
continentObj = Continents.objects.get(ckey='as45914')
countryList = Country.objects.filter(ckey=cObj)

# Get List by Related Attribute
countryList = Country.objects.filter(ckey__ckey='as45914')

edit

@OP pretty much you'd use related Attributes.

Lets say you had three models

class Continents():
    name = charfield

class Country():
    continents = Key(Continents)

class City():
    country = Key(Country)

Now how to get all Cities in Europe

list_Of_Cities = City.objects.filter(country__continents__name='Europe')

edit 2

Per your last comment, you got a Queryset from the filter (which is correct!)

If you know the Filter will always return 1 item use:

  • obj = country.objects.filter(field=value).first() - Grab the first (will be None if there's no matches)
  • obj = country.objects.get(field=value) - Get 1 (will crash if query returns zero or more than 1!)

From there you just do obj.countryName

But If the filter can return Multiple matches, here are some ways to get the values:

# QuerySet
# qs = <QuerySet [<country: country object (973)>]>

# Way 1:
names = qs.values('countryName')
# names = [{'countryName': '{name1}'}, {'countryName': '{name2}'},]
#   (Array of Dicts)


# Way 2:
names = qs.values_list('countryName')
# names = [('{name1}'), ('{name2}'),]
#   (Array of Tuples)


# Way 3:
names = qs.values_list('countryName', flat=True)
# names = ['{name1}', '{name2}',]
#   (Array of Names)


# Way 4: (Just loop)
for i in qs:
    i.countryName

for viwes

def countrylist(request):
    list_Of_Cities = country.objects.filter(ckey__ckey='as45914').values('countryName')

    context = {
         "list_Of_Cities":list_Of_Cities
  }
    return render(request,"guide/countrylist.html",context=context)

and in HTML

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>

    {% for i in list_Of_Cities %}
    {{i.countryName}}
    {% endfor %}

</body>
</html>
Related