Как вывести значение одной переменной в шаблон с помощью Django?

Я создаю веб-приложение, в котором завершение проекта (статус) возвращается клиенту (пользователю) через динамический URL. Вид выглядит примерно так:Click here to view screenshot

Я хочу получить единственное значение из поля phase (фазовое поле хранит целочисленные значения от 1 до 10) и выполнить percentage = (phase / 10) * 100. Как я могу вывести запрос phase и вывести переменную percentage, которая хранит процент, в шаблон?

Вот мой model.py:

from cmath import phase
from pyexpat import model
from django.db import models
from sqlalchemy import delete

class Project(models.Model):
    STATUS = (
        ('Inititated', 'Inititated'),
        ('Paused', 'Paused'),
        ('In progress', 'In progress'),
        ('Aborted', 'Aborted'),
        ('Completed', 'Completed')
    )

    PHASE = (
        ('1', '1'),
        ('2', '2'),
        ('3', '3'),
        ('4', '4'),
        ('5', '5'),
        ('6', '6'),
        ('7', '7'),
        ('8', '8'),
        ('9', '9'),
        ('10', '10')
    )

    p_id = models.IntegerField(null=True)
    p_name = models.CharField(max_length=100, null=True)
    c_name = models.CharField(max_length=100, null=True)
    c_mail = models.CharField(max_length=100, null=True)
    init_date = models.DateField(null=True)
    ect = models.DateField(null=True)
    status = models.CharField(max_length=200,null=True, choices=STATUS)
    collabs = models.IntegerField(null=True)
    phase = models.CharField(max_length=100,null=True, choices=PHASE)
    
    def __str__(self):
        return self.p_name

views.py:

from cmath import phase
from multiprocessing import context
import re
from unicodedata import name
from django.shortcuts import render
from django.http import HttpResponse
from .models import Project
from django.shortcuts import get_object_or_404

# views
def dashboard(request):
    projects = Project.objects.all()

    return render(request, 'accounts/dashboard.html', {'projects':projects})


def status(request, no):
    projects = get_object_or_404(Project, pk=no) 

    return render(request, 'accounts/status.html', {'projects':projects})

status.html (шаблон):

<div id="greeter">
                <h1 id="name">Hello, {{projects.c_name}}!</h1>
                <p>Your project has come this far</p>
            </div>
            <div id="frame_body">
                <div id="percentage"><h1 id="receivedVal">80<sup>%</sup></h1></div>
                <div id="proj-name"><p>{{projects.p_name}}</p></div>
                <div id="name-of-staff-head"><p>Handled by Mr. X</p></div>
                <div id="temporary">
                    <p>Status -{{projects.status}}</p> <br>
                    <p>Phase -{{projects.phase}}</p> <br>
                    <p>Collaborators -{{projects.collab}}</p> 
                </div>
            </div>

Прежде всего, если вы хотите, чтобы phage было целым числом - не храните числа как строки в вашей базе данных (фазовое поле). Вместо этого используйте IntegerField с ограничениями, чтобы ограничить число, которое может быть сохранено:

class Foo(models.Model):
    ...
    foo_count = models.PositiveIntegerField(null=True)

    class Meta:
        constraints = [
            models.CheckConstraint(
                name="%(app_label)s_%(class)s_foo_count_range",
                check=models.Q(foo_count__range=(1, 10)),
            ),
        ]

Или же вы можете использовать валидаторы полей, подробнее об этом читайте здесь

Затем вы можете создать API (любой подходящий вам - основанный на классах/функциях), например: (подробнее об APIView здесь)

class GetValue(APIView):
    class OutputSerializer(serializers.Serializer):
        phase = serializer.IntegerFiled()

    def get(self, request, project_id):
        project = get_object_or_404(Project.objects.only('phase'), id=project_id)
        data = self.OutputSerializer(project).data
        
        return Response(data)

Теперь вы можете написать javascript для вызова каждые n секунд/минут вашего API и отображения новых полученных данных.

Кроме того, вы можете сделать преобразование (percentage = (phase / 10) * 100) в представлении API, чтобы ваш front end получил то, что ему нужно, не делая никаких вычислений ИЛИ, как предложил @Marco, в качестве модельного метода.

Вернуться на верх