Несколько контекстов в одном html с помощью Templateview
У меня есть 4 типа билетов для отображения на моей приборной панели Открыт, принят, завершен и закрыт Я написал ниже шаблон представления для отображения всех контекстов с одним единственным представлением Как мне написать мой html файл в одном единственном html, который имеет одинаковые заголовки для всех данных, но отличается в таблице данных Я реализовал один, но это не работает показывает закрытые билеты во всех ссылках для открытых, принятых, завершенных и т.д. или предложите мне, должен ли я изменить что-то в представлении
Views.py
class DeveloperTicketView(TemplateView):
template_name = 'app/ticket_view.html'
def get_context_data(self, **kwargs):
context = super(DeveloperTicketView,self).get_context_data(**kwargs)
context['open_tickets'] = Ticket.objects.filter(status = 'Opened')
context['accepted_tickets'] = Ticket.objects.filter(status = 'Accepted',accepted_by = self.request.user)
context['completed_tickets'] = Ticket.objects.filter(status = 'Completed',accepted_by = self.request.user)
context['closed_tickets'] = Ticket.objects.filter(status = 'Closed',accepted_by = self.request.user)
return context
ticket_view.html
{% extends 'app/base.html' %}
{% block body %}
<table class="table table-bordered">
<thead>
<tr>
<th>ID</th>
<th>Status</th>
<th>Created</th>
<th>Title</th>
<th>Description</th>
</tr>
</thead>
{% for ticket in open_tickets %}
<tbody>
<tr>
<td><a href="">{{ ticket.id }}</a></td>
<td>{{ ticket.status }}</td>
<td>{{ ticket.created_by }}</td>
<td>{{ ticket.ticket_title }}</td>
<td>{{ ticket.ticket_description }}</td>
<td><a href="{% url 'accept_tickets' pk=ticket.id %}">Accept</a>
</tr>
</tbody></table>
{% endfor %}
{% for ticket in accepted_tickets %}
<tbody>
<tr>
<td><a href="">{{ ticket.id }}</a></td>
<td>{{ ticket.status }}</td>
<td>{{ ticket.created_by }}</td>
<td>{{ ticket.ticket_title }}</td>
<td>{{ ticket.ticket_description }}</td>
<td><a href="{% url 'mark_complete' pk=ticket.id %}">Complete</a>
</tr>
</tbody></table>
{% endfor %}
{% for ticket in completed_tickets %}
<tbody>
<tr>
<td><a href="">{{ ticket.id }}</a></td>
<td>{{ ticket.status }}</td>
<td>{{ ticket.created_by }}</td>
<td>{{ ticket.ticket_title }}</td>
<td>{{ ticket.ticket_description }}</td>
</tr>
</tbody></table>
{% endfor %}
{% for ticket in closed_tickets %}
<tbody>
<tr>
<td><a href="">{{ ticket.id }}</a></td>
<td>{{ ticket.status }}</td>
<td>{{ ticket.created_by }}</td>
<td>{{ ticket.ticket_title }}</td>
<td>{{ ticket.ticket_description }}</td>
</tr>
</tbody></table>
{% endfor %}
{% endblock %}
models.py
class Ticket(models.Model):
ticket_title = models.CharField(max_length=200)
ticket_description = models.TextField()
created_by = models.ForeignKey(User,related_name = 'created_by',blank=True,null=True,on_delete=models.CASCADE)
STATUS_CHOICES = (
('Opened','Opened'),
('Accepted','Accepted'),
('Completed','Completed'),
('Closed','Closed')
)
status = models.CharField('Status',choices=STATUS_CHOICES,max_length = 100,default = 'Opened')
closed_date = models.DateTimeField(blank=True,null=True)
completed_date = models.DateTimeField(blank=True,null=True)
accepted_date = models.DateTimeField(blank=True,null=True)
opened_date = models.DateTimeField(blank=True,null=True)
accepted_by = models.ForeignKey(User,related_name='assigned_to',on_delete=models.CASCADE,blank=True,null=True)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
def __str__(self):
return self.ticket_title
изображения приборной панели изображение приборной панели, которое показывает ссылку Для каждой ссылки он показывает все тикеты, как на этом изображении для открытого приема и т.д. Данные на этом изображении рендеринг
Исходя из вашего скриншота и ответов, у вас есть несколько проблем, основанных на некорректном HTML.
- Не все ваши ТД закрываются
- У вас несколько tbody и закрывающих тегов таблиц, но только один открывающий тег таблицы
- Ваши forloops находятся не на той стороне tbody
Есть два способа сделать это
Вариант 1
Оставьте свой вид следующим образом:
class DeveloperTicketView(TemplateView):
template_name = 'app/ticket_view.html'
def get_context_data(self, **kwargs):
context = super(DeveloperTicketView,self).get_context_data(**kwargs)
context['open_tickets'] = Ticket.objects.filter(status = 'Opened')
context['accepted_tickets'] = Ticket.objects.filter(status = 'Accepted',accepted_by = self.request.user)
context['completed_tickets'] = Ticket.objects.filter(status = 'Completed',accepted_by = self.request.user)
context['closed_tickets'] = Ticket.objects.filter(status = 'Closed',accepted_by = self.request.user)
return context
Сделайте свой шаблон таким образом, чтобы итерация каждого кверисета по очереди добавляла записи в одну таблицу
{% extends 'app/base.html' %}
{% block body %}
<table class="table table-bordered">
<thead>
<tr>
<th>ID</th>
<th>Status</th>
<th>Created</th>
<th>Title</th>
<th>Description</th>
</tr>
</thead>
<tbody>
{% for ticket in open_tickets %}
<tr>
<td><a href="">{{ ticket.id }}</a></td>
<td>{{ ticket.status }}</td>
<td>{{ ticket.created_by }}</td>
<td>{{ ticket.ticket_title }}</td>
<td>{{ ticket.ticket_description }}</td>
<td><a href="{% url 'accept_tickets' pk=ticket.id %}">Accept</a></td>
</tr>
{% endfor %}
{% for ticket in accepted_tickets %}
<tr>
<td><a href="">{{ ticket.id }}</a></td>
<td>{{ ticket.status }}</td>
<td>{{ ticket.created_by }}</td>
<td>{{ ticket.ticket_title }}</td>
<td>{{ ticket.ticket_description }}</td>
<td><a href="{% url 'mark_complete' pk=ticket.id %}">Complete</a></td>
</tr>
{% endfor %}
{% for ticket in completed_tickets %}ticket.status
<tr>
<td><a href="">{{ ticket.id }}</a></td>
<td>{{ ticket.status }}</td>
<td>{{ ticket.created_by }}</td>
<td>{{ ticket.ticket_title }}</td>
<td>{{ ticket.ticket_description }}</td>
</tr>
{% endfor %}
{% for ticket in closed_tickets %}
<tr>
<td><a href="">{{ ticket.id }}</a></td>
<td>{{ ticket.status }}</td>
<td>{{ ticket.created_by }}</td>
<td>{{ ticket.ticket_title }}</td>
<td>{{ ticket.ticket_description }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}
Вариант 2 - Предпочтительный метод
Измените представление и шаблон, чтобы выполнять меньше запросов и выполнять меньше итераций, тем самым повышая производительность. Вы можете сделать это, используя объекты Q() в фильтре. Это также сократит объем кода. В этом примере я объединил четыре набора запросов в один. Если вы хотите сгруппировать их, просто добавьте order_by('status') в конце
from django.db.models import Q
class DeveloperTicketView(TemplateView):
template_name = 'app/ticket_view.html'
def get_context_data(self, **kwargs):
context = super(DeveloperTicketView,self).get_context_data(**kwargs)
context['tickets'] = Ticket.objects.filter(
Q(status = 'Opened') | Q(status__in=['Accepted'. 'Completed', 'Closed'], accepted_by=self.request.user)
)
return context
Тогда ваш шаблон также может быть сокращен. Вы все еще можете иметь якоря, выполняющие различные действия, вы просто проверяете значение status и затем добавляете якорь. Это сократило количество итераций
{% extends 'app/base.html' %}
{% block body %}
<table class="table table-bordered">
<thead>
<tr>
<th>ID</th>
<th>Status</th>
<th>Created</th>
<th>Title</th>
<th>Description</th>
</tr>
</thead>
<tbody>
{% for ticket in tickets %}
<tr>
<td><a href="">{{ ticket.id }}</a></td>
<td>{{ ticket.status }}</td>
<td>{{ ticket.created_by }}</td>
<td>{{ ticket.ticket_title }}</td>
<td>{{ ticket.ticket_description }}</td>
<td>
{% if ticket.status == 'Opened' %}
<a href="{% url 'accept_tickets' pk=ticket.id %}">Accept</a>
{% elif ticket.status == 'Accepted' %}
<a href="{% url 'mark_complete' pk=ticket.id %}">Complete</a>
{% endif %}
<td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}
Если вы хотите еще больше повысить производительность, добавьте составной индекс к status и accepted_by, в таком порядке. Тогда запрос будет использовать этот индекс, а не сканирование таблицы