为了账号安全,请及时绑定邮箱和手机立即绑定

Django-Tables2从字典中添加额外的列

Django-Tables2从字典中添加额外的列

繁星点点滴滴 2021-05-14 17:05:55
抱歉,如果您之前曾提出过此问题,但我找不到特定的用例回答。我有一个显示基本产品信息的表。产品详细信息(例如价格,销售数量和卖方数量)会定期进行抓取,并存储在单独的数据库表中。现在,我想使用tables2在前端的一个表中同时显示基本产品信息和详细信息。为此,我在产品模型中编写了一个函数,以获取最新的详细信息并将其作为字典返回,从而可以使用单个Accessor调用。# models.pyclass 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.pyclass ProductTable(tables.Table):    productBrand = tables.Column(        accessor=Accessor('brand.name'),        verbose_name='Brand'    )    currentRank = tables.Column(        accessor=Accessor('currentRank')    )    class Meta:        model = Product        ...现在如何使用此返回的字典并将其拆分为“产品”表中的列?除了我的操作方式之外,还有其他方法可以使用访问器吗?
查看完整描述

1 回答

?
天涯尽头无女友

TA贡献1831条经验 获得超9个赞

您可以使用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项目


查看完整回答
反对 回复 2021-05-25
  • 1 回答
  • 0 关注
  • 93 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信