Я пытаюсь связать django_table с подробной страницей, которая отображает эту строку с некоторыми дополнительными данными.
Я перепробовал все учебники, которые смог найти, чтобы связать столбцы таблицы с идентификатором. В документации не так много подробностей, как это сделать.
Здесь, в CustomerListView, все работает нормально. Я могу отобразить свои блоки фильтров и таблицу, но не могу понять, как связать результаты с деталями
views.py
from django.views.generic import ListView
from django.core.exceptions import ObjectDoesNotExist
from django.db.models.query_utils import Q
from django_tables2 import RequestConfig
from braces.views import LoginRequiredMixin, GroupRequiredMixin
from .tables import CustomerTable
from .utils import PagedFilteredTableView
from cameras.models import Camera, ErrorLog
from .forms import CustomerListFormHelper
from .filters import CustomerListFilter
class CustomerListView(LoginRequiredMixin, GroupRequiredMixin, PagedFilteredTableView):
model = Camera
template_name = 'customers.html'
context_object_name = 'camera'
ordering = ['-id']
group_required = u'company-user'
table_class = CustomerTable
filter_class = CustomerListFilter
formhelper_class = CustomerListFormHelper
def get_queryset(self):
qs = super(CustomerListView, self).get_queryset()
return qs
def post(self, request, *args, **kwargs):
return PagedFilteredTableView.as_view()(request)
def get_context_data(self, **kwargs):
context = super(CustomerListView, self).get_context_data(**kwargs)
context['nav_customer'] = True
search_query = self.get_queryset()
table = CustomerTable(search_query)
RequestConfig(self.request, paginate={'per_page': 20}).configure(table)
context['table'] = table
return context
def detail_view(request, id=1):
movie= get_object_or_404(Camera, id=id)
context= {'camera': Camera,
}
return render(request, 'detail_view.html', context)
tables.py
import django_tables2 as tables
from django_tables2.utils import A
from cameras.models import Camera, ErrorLog
class CustomerTable(tables.Table):
# transform=lambda obj: '<a href="{}">{}</a>'.format(obj.get_absolute_url(), str(obj))
serial_number = tables.LinkColumn('customer-detail', args=[A('pk')])
name = tables.LinkColumn('customer-detail', args=[A('pk')])
bom = tables.LinkColumn('customer-detail', args=[A('pk')])
firmware = tables.LinkColumn('customer-detail', args=[A('pk')])
health = tables.LinkColumn('customer-detail', args=[A('pk')])
class Meta:
model = Camera
fields = ('serial_number', 'name', 'bom', 'firmware', 'health')
attrs = {"class": "table-striped table-bordered"}
empty_text = "There are no customers matching the search criteria..."
model.py
class Camera(TimeStampedModel):
public_identifier = models.UUIDField(unique=True,
default=uuid.uuid4,
editable=False)
serial_number = models.CharField(max_length=100,
unique=True,
null=True)
name = models.CharField(max_length=50, blank=True, null=True)
group = models.ForeignKey('CameraGroup',
on_delete=models.SET_NULL,
null=True,
related_name='cameras',
related_query_name='cameras')
group_tracker = FieldTracker(fields=('group',))
# identifier from assembly (what parts does the camera consist of)
bom = models.CharField(max_length=50, blank=True, null=True)
# what firmware is the camera on (mender artifact name)
firmware = models.CharField(max_length=50, blank=True, null=True)
focus_left = models.CharField(max_length=50, blank=True, null=True)
focus_right = models.CharField(max_length=50, blank=True, null=True)
# last seen at ip
last_sighting_ip = models.CharField(max_length=50, blank=True, null=True)
last_sighting_time = models.DateTimeField(null=True, blank=True)
# json blob that the camera can send home w. health status
health = models.TextField(blank=True)
objects = CameraQuerySet.as_manager()
def __str__(self):
return self.name or self.serial_number or str(self.public_identifier)
def as_json(self):
return {
'serial_number': self.serial_number
}
def get_absolute_url(self):
return reverse('customer-detail', args=[str(self.id)])
class ErrorLog(TimeStampedModel):
ERROR_TYPES = (
('S', 'Software'),
('H', 'Hardware'),
('O', 'Other'),
)
error_type = models.CharField(max_length=100, blank=True, null=True,
choices=ERROR_TYPES)
error_message = models.CharField(max_length=1000, blank=True, null=True)
last_sighting_time = models.DateTimeField(null=True, blank=True)
camera = models.ForeignKey(Camera, null=True, on_delete=models.CASCADE,
verbose_name="serial number")
contact = models.CharField(max_length=200, blank=True, null=True)
def __str__(self):
return self.error_message
def get_absolute_url(self):
return reverse('error-detail-view', args=[str(self.id)])
customers.html
{% extends "base.html" %}
{% load bootstrap4 %}
{% load querystring from django_tables2 %}
<body>
{% block content %}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js" integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin="anonymous"></script>
<thead>
<tr>
<th>
<form method="post" >
{% csrf_token %}
<div>
<button type="submit" > Search</button>
</div>
</form>
</th>
</tr>
<tr>
{% for column in table.columns %}
{% if column.orderable %}
<th {{ column.attrs.th.as_html }}><a href="{% querystring table.prefixed_order_by_field=column.order_by_alias.next %}">{{ column.header|title }}</a></th>
{% else %}
<th>{{ column.header|title }}</th>
{% endif %}
{% endfor %}
</tr>
</thead>
<tbody>
{% for row in table.page.object_list|default:table.rows %} {# support pagination #}
{% block table.tbody.row %}
<tr class="{% cycle "odd" "even" %}">
{% for column, cell in row.items %}
<td {{ column.attrs.td.as_html }}>{{ cell }}</td>
{% endfor %}
</tr>
{% endblock table.tbody.row %}
{% empty %}
{% if table.empty_text %}
{% block table.tbody.empty_text %}
<tr><td colspan="{{ table.columns|length }}">{{ table.empty_text }}</td></tr>
{% endblock table.tbody.empty_text %}
{% endif %}
{% endfor %}
</tbody>
</table>
</div>
{% endblock %}
</body>
detail_view.html
<html>
<head>
<meta charset="UTF-8">
<title>Cameras</title>
</head>
<body>
<h1>{{ camera.name }}</h1>
<a href="{{camera.get_absolute_url}}">Link</a>
{% for obj in object_list %}
<a href="{{camera.get_absolute_url}} ">{{obj.serial_number}}</a> <br>
{% endfor %}
<p>Serial number: {{ camera.serial_number }}</p>
<p>Firmware: {{ camera.firmware }}</p>
<p>Health: {{ camera.health }}</p>
<p>Go back to the <a href="/customers/">list of movies </a></p>
</body>
</html>