hoangphi01
hoangphi01

Reputation: 23

How to call model in Django

I'm writing a project with Django that can manage citizens with their passports. But today when I created an HTML page to represent the database, I have encountered an error. My purpose of this webpage is show to user the info includes (citizen name, citizen sex, the birthday of citizen, passport type, passport number, and valid time of citizen's passport).

All of citizen information, I have put in Citizen table. With passport of citizen, I have put in Passport table. The HTML page have represented all the information of Citizen table, but cannot represent informations in Passport table and I don't know why.

I don't know what I have wrong.

Here is my code: models.py

class Passport(models.Model):
    Number = models.CharField(max_length=8, default=1)
    pType = models.CharField(max_length=1)
    validTime = models.DateField()
    pLocation = models.ForeignKey(Manager, on_delete=models.CASCADE, 
        null=True, default=None, related_name="passport",
        )

    def __str__(self):
        return f"{self.Number} ({self.pType})" 

class Citizen(models.Model):
    sID = models.OneToOneField(
        Passport, on_delete=models.CASCADE, 
        default=1,
    )
    name = models.CharField(max_length=64)
    sex = models.CharField(max_length=1)
    year = models.DateField()
    code = models.BigAutoField(primary_key=True, default=None)

    def __str__(self):
        return f"{self.name} ({self.sex})"

urls.py

from django.urls import path

from . import views

app_name = 'citizens'
urlpatterns = [
    path("", views.index, name="index", ),
    path("<int:citizen_id>", views.citizen, name="citizen"),
    path("<int:citizen_id>/passport", views.passport, name="passport")
]
    

views.py

from django.shortcuts import render
from django.http import HttpResponseBadRequest, HttpResponseRedirect, Http404
from django.urls import reverse

from .models import Citizen, Passport

# Create your views here.
def index(request):
    return render(request, "citizens/index.html", {
        "citizens": Citizen.objects.all()
    })

def citizen(request, citizen_id):
    try:
        citizen = Citizen.objects.get(code=citizen_id)
    except Citizen.DoesNotExist:
        raise Http404("Citizen not found")
    return render(request, "citizens/citizen.html", {
        "citizen": citizen,
        
        
    })


def passport(request, citizen_id):
    try:
        passport = Passport.objects.get(Number=passport_id)
        citizen = Citizen.objects.get(code=citizen_id)
    except KeyError:
        return HttpResponseBadRequest("Bad request: No passport found")
    except Citizen.DoesNotExist:
        return HttpResponseBadRequest("Bad request: No citizen found")
    except Passport.DoesNotExist:
        return HttpResponseBadRequest("Bad request: No passport found")    
    return HttpResponseRedirect("citizen", args=(citizen_id,))

And the HTML page: citizen.html

{% extends "citizens/layout.html" %}

{% block body %}
    <h1>Citizen {{ citizen.sID }}</h1>
    <ul>
        <li>Tên công dân: {{ citizen.name }} </li>
        <li>Giới tính: {{ citizen.sex }}</li>
        <li>Năm sinh: {{ citizen.year }}</li>
    </ul>

    <h2>Passport:</h2>
    <ul>
        
        <li>Loại hộ chiếu: {{ passport.pType }} </li>
        <li>Số hộ chiếu: {{ passport.Number }}</li>
        <li>Thời hạn hiệu lực: {{ passport.validTime }}</li>
        
    </ul>

    <a href="{% url 'citizens:index' %}">Quay lại</a>
{% endblock %}

Thank you.

Upvotes: 1

Views: 118

Answers (1)

Abdul Aziz Barkat
Abdul Aziz Barkat

Reputation: 21807

You have only passed citizen into the context (you haven't passed passport in the context). To access the related Passport of the citizen you can write citizen.sID (the name of your OneToOneField), hence in your template you can write:

<h2>Passport:</h2>

<ul>
    <li>Loại hộ chiếu: {{ citizen.sID.pType }} </li>
    <li>Số hộ chiếu: {{ citizen.sID.Number }}</li>
    <li>Thời hạn hiệu lực: {{ citizen.sID.validTime }}</li>
    
</ul>

Upvotes: 1

Related Questions