簡體   English   中英

Django-Tables2從字典中添加額外的列

[英]Django-Tables2 add extra columns from dictionary

抱歉,如果您之前曾提出過此問題,但我找不到特定的用例回答。

我有一個顯示基本產品信息的表。 產品詳細信息(例如價格,銷售數量和銷售商數量)會定期進行抓取,並存儲在單獨的數據庫表中。 現在,我想使用tables2在前端的一個表中同時顯示基本產品信息和詳細信息。 為此,我在產品模型中編寫了一個函數,以獲取最新的詳細信息並將其作為字典返回,從而可以使用單個Accessor調用。

# models.py

class Product(models.Model):
    created_at = models.DateTimeField(auto_now_add=True)

    name = models.CharField(max_length=256)
    brand = models.ForeignKey(Brand)
    category = models.CharField(max_length=128, choices=CATEGORY_CHOICES)

    def __unicode__(self):
        return self.name

    def currentState(self):
        currentDetailState = ProductDetailsState.objects.filter(
            product=self
        ).latest('created_at')

        # return current details as a dictionary
        return {
            price: currentDetailState.price,
            num_sellers: currentDetailState.num_sellers,
            num_sales: currentDetailState.num_sales
        }


class ProductDetailsState(models.Model):
    product = models.ForeignKey(Product)
    created_at = models.DateTimeField(auto_now_add=True)

    price = models.DecimalField(max_digits=6, decimal_places=2, null=True)

    num_sellers = models.IntegerField(null=True)
    num_sales = models.IntegerField(null=True)

    def __unicode__(self):
        return self.created_at



# tables.py

class ProductTable(tables.Table):
    productBrand = tables.Column(
        accessor=Accessor('brand.name'),
        verbose_name='Brand'
    )
    currentRank = tables.Column(
        accessor=Accessor('currentRank')
    )

    class Meta:
        model = Product
        ...

現在如何使用此返回的字典並將其拆分為“產品”表中的列? 除了我的使用方式,還有其他使用訪問器的方法嗎?

您可以使用Accessor遍歷dict,因此應執行以下操作:

class ProductTable(tables.Table):
    # brand is the name of the model field, if you use that as the column name, 
    # and you have the __unicode__ you have now, the __unicode__ will get called, 
    # so you can get away with jus this:
    brand = tables.Column(verbose_name='Brand')
    currentRank = tables.Column()

    # ordering on the value of a dict key is not possible, so better to disable it.
    price = tables.Column(accessor=tables.A('currentState.price'), orderable=False)
    num_sellers = tables.Column(accessor=tables.A('currentState.num_sellers'), orderable=False)
    num_sales = tables.Column(accessor=tables.A('currentState.num_sales'), orderable=False)

    class Meta:
        model = Product

雖然這可行,但排序也很不錯。 為此,您的'currentState'方法有點麻煩,您應該更改傳遞給表的QuerySet。 此視圖顯示了它如何工作:

from django.db.models import F, Max
from django.shortcuts import render
from django_tables2 import RequestConfig

from .models import Product, ProductDetailsState
from .tables import ProductTable


def table(request):
    # first, we make a list of the post recent ProductDetailState instances
    # for each Product.
    # This assumes the id's increase with the values of created_at, 
    # which probably is a fair assumption in most cases.
    # If not, this query should be altered a bit.
    current_state_ids = Product.objects.annotate(current_id=Max('productdetailsstate__id')) \
        .values_list('current_id', flat=True)

    data = Product.objects.filter(productdetailsstate__pk__in=current_state_ids)

    # add annotations to make the table definition cleaner.
    data = data.annotate(
        price=F('productdetailsstate__price'),
        num_sellers=F('productdetailsstate__num_sellers'),
        num_sales=F('productdetailsstate__num_sales')
    )
    table = ProductTable(data)
    RequestConfig(request).configure(table)

    return render(request, 'table.html', {'table': table})

使用上面創建的注釋可以簡化表的定義:

class ProductTable(tables.Table):
    brand = tables.Column(verbose_name='Brand')
    currentRank = tables.Column()

    price = tables.Column()
    num_sellers = tables.Column()
    num_sales = tables.Column()

    class Meta:
        model = Product

您可以在github上找到完整的django項目

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM