Связывание внешних ключей с помощью Django Tables2 и Slugs
Я пытаюсь построить сводные таблицы с кликабельными ссылками, которые позволяют перейти на более низкие уровни. Иерархия в порядке убывания выглядит следующим образом: подразделение -> регион -> филиал -> центр прибыли, где каждый центр прибыли может иметь несколько "дебиторских задолженностей". Я хочу, чтобы в сводном представлении подразделения отображались все регионы (например, Калифорния, Центральный Техас, Огайо и т.д.) и сумма "total_amount" для регионов. Я хочу, чтобы можно было щелкнуть регион, и он опускался вниз к филиалам, где я мог бы увидеть сводку по каждому филиалу. И так далее и тому подобное
Я потратил на это гораздо больше времени, чем хотел бы признаться, и строки, закомментированные в tables.py, - это лишь малая часть того, что я пробовал.
Что я упускаю?
class Division(models.Model):
name = models.CharField(max_length=128, unique=True)
slug = models.SlugField(unique=True, null=True)
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('division-detail', args=[str(self.slug)])
class Region(models.Model):
name = models.CharField(max_length=128, unique=True)
division = models.ForeignKey('Division', to_field='name', on_delete=models.CASCADE)
slug = models.SlugField(unique=True, null=True)
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('region-summary', args=[str(self.slug)])
def save(self, *args, **kwargs):
if not self.slug:
self.slug = slugify(self.name)
super().save(*args, **kwargs)
class Branch(models.Model):
name = models.CharField(max_length=128)
number = models.CharField(max_length=4, unique=True)
region = models.ForeignKey('Region', to_field='name', on_delete=models.CASCADE)
slug = models.SlugField(unique=True, null=True)
def __str__(self):
return self.number
def save(self, *args, **kwargs):
if not self.slug:
self.slug = slugify(self.number)
super().save(*args, **kwargs)
def get_absolute_url(self):
return reverse('branch-detail', args=[str(self.slug)])
class Profit_Center(models.Model):
branch = models.ForeignKey('Branch', on_delete=models.CASCADE)
number = models.CharField(max_length=32, unique=True, editable=False, null=True, blank=True)
slug = models.SlugField(unique=True, null=True)
class Receivable(models.Model):
document = models.IntegerField(primary_key=True, blank=False)
payer = models.ForeignKey('Payer', on_delete=models.PROTECT)
profit_center = models.ForeignKey(Profit_Center, to_field = 'number', on_delete=models.PROTECT, null=True)
total_amount = models.DecimalField(decimal_places=2, max_digits=20, null=True, blank=True)
slug = models.SlugField(unique=True, null=True, editable=False)
tables.py
#summary by selected division, showing summary by region
class ReceivableDivisionSummaryHTMxTable(tables.Table):
#profit_center__branch__region = tables.Column(linkify=('region-summary', {'slug': 'central-texas'})) #always goes to central texas
#profit_center__branch__region = tables.Column(linkify=('region-summary', {'region': tables.A('region'), 'slug': tables.A('region.slug')})) #fails on accessor key
#profit_center__branch__region = tables.Column(linkify=('region-summary', {'slug': tables.A('profit_center__branch__region.slug')}))
#profit_center__branch__region = tables.Column(linkify=('region-summary', {'slug': tables.A('name')})) #fails on accessor key
#profit_center__branch__region = tables.LinkColumn('region-summary', args=[A('profit_center__branch__region.slug')])
#profit_center__branch__region = tables.Column(linkify=True)
#profit_center__branch__region = tables.LinkColumn('region-summary', kwargs={'slug': 'record.slug'}) #half-ass works, returns regionsummary/region_slug insteald of the real slug
#profit_center__branch__region = tables.LinkColumn('region-summary', args=[A('pk')])
#profit_center__branch__region = tables.Column(linkify=('region-summary', {'pk': tables.A('region__pk')})) #half-ass works, returns regionsummary/region_slug insteald of the real slug
#profit_center__branch__region = tables.LinkColumn('region-summary', args=[A('slug')])
#profit_center__branch__region = tables.Column(linkify=('region-summary', {'slug': tables.A('region.slug')}))
#species =tables.TemplateColumn('<a href="{% url "main:species" name value %}">{{value}}</a>')
profit_center__branch__region = tables.TemplateColumn('<a href="{% url "region-summary" slug %}">{{value}}</a>') #sooooo fucking close, returns the division- (e.g. Ford) rather region (e.g. Ohio), though it displays Ohio correctly as the value
class Meta:
model = Receivable
template_name = 'tables/bootstrap_htmx.html'
fields = ('profit_center__branch__region', 'sum_col')
views.py
def ReceivableDivisionSummaryHTMxTableView(request, slug):
#post = get_object_or_404(Receivable, slug=slug)
queryset = Receivable.objects.values('profit_center__branch__region').annotate(sum_col=Sum('total_amount'))
table= ReceivableDivisionSummaryHTMxTable(queryset)
context = {'table': table, 'slug': slug}
if request.htmx:
template_name = "app/receivable_table_partial.html"
else:
template_name = 'app/receivable_summary_htmx.html'
template_name
return render(request, template_name, context)
def ReceivableRegionSummaryHTMxTableView(request, slug):
queryset = Receivable.objects.values('profit_center').annotate(sum_col=Sum('total_amount'))
table= ReceivableRegionSummaryHTMxTable(queryset)
context = {'table': table, 'slug':slug}
if request.htmx:
template_name = "app/receivable_table_partial.html"
else:
template_name = 'app/receivable_summary_htmx.html'
template_name
return render(request, template_name, context)
Обновление 4: пошло другим путем. Вместо того, чтобы иметь divisionsummay/NAMEOFDIVSION/regionsummary/NAMEOFREGION, я просто буду иметь отдельные урлы (например, app/htmx/divisionsummary/NAMEOFDIVISON, app/htmx/regionsummary/NAMEOFREGION и т.д.).
Достигается следующим образом:
def render_profit_center__branch__region(self, value):
return format_html('<a href="{}">{}</a>', reverse_lazy('region-summary', args=[slugify(value)]), value)