GVKun编程网logo

django admin启用对计算字段的排序(django中admin)

26

本篇文章给大家谈谈djangoadmin启用对计算字段的排序,以及django中admin的知识点,同时本文还将给你拓展DjangoAdminCookbook-10如何启用对计算字段的过滤、Djang

本篇文章给大家谈谈django admin启用对计算字段的排序,以及django中admin的知识点,同时本文还将给你拓展Django Admin Cookbook-10如何启用对计算字段的过滤、Django Admin Cookbook-15 如何在 Django Admin 后台模型列表页面中添加自定义操作按钮、Django Admin Cookbook-16如何使用Django Admin管理后台导入CSV、Django Admin Cookbook-38如何获取特定对象的Django Admin后台URL等相关知识,希望对各位有所帮助,不要忘了收藏本站喔。

本文目录一览:

django admin启用对计算字段的排序(django中admin)

django admin启用对计算字段的排序(django中admin)

我的数据库表和模型中有以下两个字段(模型名称:Order):

id, branch_id, product_id, cost, quantity, status, ordered_at

我的OrderModelAdmin中包含以下代码:

list_display = (    ''order_number'',    ''branch'',    ''product'',    ''cost'',    ''quantity'',    ''calculated_total'',    ''status'',    ''ordered_at'',)def calculated_total(self, obj):    return obj.cost * obj.quantitycalculated_total.short_description = _(''Total'')

现在,我要为此字段启用排序。实际上,我要做的就是
在SELECT语句中添加一列:

 SELECT (t.cost * t.quantity) as TOTAL ORDER BY TOTAL

有没有一种方法可以在Django Admin中附加SQL语句进行排序?

答案1

小编典典

无法通过calculated_total方法的结果进行排序。

但是,您可以通过覆盖模型admin
的 方法,并通过计算相同内容的 表达式进行排序,来设置模型admin的默认排序。
get_queryset, and ordering by an
expression that calculates the same thing.

class OrderModelAdmin(admin.ModelAdmin):    ...    def get_queryset(self, request):        qs = super(OrderModelAdmin, self).get_queryset(request)        qs = qs.order_by(F(''cost'')*F(''quantity''))        return qs

一种类似的方法是用总数注释查询集,然后
按该字段排序。假设成本为a DecimalField,数量为aIntegerField,则需要使用ExpressionWrapper来设置输出字段。
有关更多信息,请参见有关将F()与
注释一起使用的文档。

我认为无法total直接在中使用list_display。但是,您可以更改calculated_total方法以访问带注释的字段。我们进行了设置,calculated_total.admin_order_field = ''total''以便
Django管理员允许您通过单击对该列进行排序。

from django.db.models import F, ExpressionWrapper, DecimalFieldclass OrderModelAdmin(admin.ModelAdmin):    list_display = [''name'', ''number'', ''price'', ''calculated_total'']    def calculated_total(self, obj):        return obj.total    calculated_total.admin_order_field = ''total''    def get_queryset(self, request):        qs = super(OrderModelAdmin, self).get_queryset(request)        qs = qs.annotate(total=ExpressionWrapper(F(''cost'')*F(''quantity''), output_field=DecimalField())).order_by(''total'')        return qs

Django Admin Cookbook-10如何启用对计算字段的过滤

Django Admin Cookbook-10如何启用对计算字段的过滤

10.如何启用对计算字段的过滤?

假设你admin.py中的Hero管理模型如下:

@admin.register(Hero)
class HeroAdmin(admin.ModelAdmin):
    list_display = ("name", "is_immortal", "category", "origin", "is_very_benevolent")
    list_filter = ("is_immortal", "category", "origin",)
    def is_very_benevolent(self, obj):
        return obj.benevolence_factor > 75

它具有一个计算字段is_very_benevolent,Admin后台显示如下:

我们已经在来自模型属性字段上添加了过滤,但是还想在计算出的字段上添加过滤。为此,我们可以通过继承SimpleListFilter类实现:

class IsVeryBenevolentFilter(admin.SimpleListFilter):
    title = ''is_very_benevolent''
    parameter_name = ''is_very_benevolent''
    def lookups(self, request, model_admin):
        return (
            (''Yes'', ''Yes''),
            (''No'', ''No''),
        )
    def queryset(self, request, queryset):
        value = self.value()
        if value == ''Yes'':
            return queryset.filter(benevolence_factor__gt=75)
        elif value == ''No'':
            return queryset.exclude(benevolence_factor__gt=75)
        return queryset

然后将更改list_filter为list_filter = ("is_immortal", "category", "origin", IsVeryBenevolentFilter)

这样,便可以对计算出的字段进行过滤。修改后管理后台显示如下:

返回目录

Django Admin Cookbook-15 如何在 Django Admin 后台模型列表页面中添加自定义操作按钮

Django Admin Cookbook-15 如何在 Django Admin 后台模型列表页面中添加自定义操作按钮

15. 如何在 Django Admin 后台模型列表页面中添加自定义操作按钮?

UMSRA 之前决定,如果有足够的 k 石,所有 Hero 英雄都可以死亡。但是,他们希望能够改变主意,让所有 Hero 英雄都可以永生。

你需要添加两个按钮:一个按钮使所有英雄都可以死亡,而另一个按钮使所有英雄永生。由于它会影响所有英雄,而与选择无关,因此这需要一个单独的按钮,而不是操作下拉菜单。

首先,我们要更改 HeroAdmin 管理模型使用的模板文件,以便我们可以添加两个按钮:

@admin.register(Hero)
class HeroAdmin(admin.ModelAdmin, ExportCsvMixin):
    change_list_template = "entities/heroes_changelist.html"

然后,我们需要覆盖 get_urls 方法,并在管理模型上添加 set_immortal 和 set_mortal 方法。它们将用作两种 view 视图:

def get_urls(self):
    urls = super().get_urls()
    my_urls = [
        path(''immortal/'', self.set_immortal),
        path(''mortal/'', self.set_mortal),
    ]
    return my_urls + urls
def set_immortal(self, request):
    self.model.objects.all().update(is_immortal=True)
    self.message_user(request, "All heroes are now immortal")
    return HttpResponseRedirect("../")
def set_mortal(self, request):
    self.model.objects.all().update(is_immortal=False)
    self.message_user(request, "All heroes are now mortal")
    return HttpResponseRedirect("../")

最后,我们通过扩展 admin/change_list.html 来创建模板文件 entities/heroes_changelist.html:

{% extends ''admin/change_list.html'' %}
{% block object-tools %}
    <div>
        <form action="immortal/" method="POST">
            {% csrf_token %}
                <button type="submit">Make Immortal</button>
        </form>
        <form action="mortal/" method="POST">
            {% csrf_token %}
                <button type="submit">Make Mortal</button>
        </form>
    </div>
    <br />
    {{ block.super }}
{% endblock %}

在点击页面的 make_mortal 动作后,英雄全都可以死亡,你会看到如下消息提示。

返回目录

Django Admin Cookbook-16如何使用Django Admin管理后台导入CSV

Django Admin Cookbook-16如何使用Django Admin管理后台导入CSV

16.如何使用Django Admin管理后台导入CSV?

假设你需要允许在Hero管理页面上导入CSV数据。为此,您需要添加一个指向更改Hero列表页面的链接,点击这个链接会跳转到上传页面。你需要编写一个处理POST请求的方法,来从CSV文件中获取数据对象:

class CsvImportForm(forms.Form):
    csv_file = forms.FileField()
@admin.register(Hero)
class HeroAdmin(admin.ModelAdmin, ExportCsvMixin):
    ...
    change_list_template = "entities/heroes_changelist.html"
    def get_urls(self):
        urls = super().get_urls()
        my_urls = [
            ...
            path(''import-csv/'', self.import_csv),
        ]
        return my_urls + urls
    def import_csv(self, request):
        if request.method == "POST":
            csv_file = request.FILES["csv_file"]
            reader = csv.reader(csv_file)
            # Create Hero objects from passed in data
            # ...
            self.message_user(request, "Your csv file has been imported")
            return redirect("..")
        form = CsvImportForm()
        payload = {"form": form}
        return render(
            request, "admin/csv_form.html", payload
        )

然后创建模板文件entities/heroes_changelist.html,以覆盖原有的admin/change_list.html:

{% extends ''admin/change_list.html'' %}
{% block object-tools %}
    <a href="import-csv/">Import CSV</a>
    <br />
    {{ block.super }}
{% endblock %}

最后,创建上传页面csv_form.html:

{% extends ''admin/base.html'' %}
{% block content %}
    <div>
        <form action="." method="POST" enctype="multipart/form-data">
            {{ form.as_p }}
            {% csrf_token %}
                <button type="submit">Upload CSV</button>
        </form>
    </div>
    <br />
{% endblock %}

修改完后,会在更改Hero后台列表页面上会有一个Import CSV的链接.

点击后上传页面显示如下。

返回目录

Django Admin Cookbook-38如何获取特定对象的Django Admin后台URL

Django Admin Cookbook-38如何获取特定对象的Django Admin后台URL

38.如何获取特定对象的Django Admin后台URL?

Hero模型有一个children字段,显示每个英雄的孩子的名字。你被要求将每个childrin链接到Hero模型更改页面。实现如下:

@admin.register(Hero)
class HeroAdmin(admin.ModelAdmin, ExportCsvMixin):
    ...
    def children_display(self, obj):
        display_text = ", ".join([
            "<a href={}>{}</a>".format(
                    reverse(''admin:{}_{}_change''.format(obj._meta.app_label, obj._meta.model_name),
                    args=(child.pk,)),
                child.name)
             for child in obj.children.all()
        ])
        if display_text:
            return mark_safe(display_text)
        return "-"

以上的reverse(''admin:{}_{}_change''.format(obj._meta.app_label, obj._meta.model_name), args=(child.pk,))返回一个对象后台修改页的URL。

其他页面如下:

  • 删除页URL: reverse(''admin:{}_{}_delete''.format(obj._meta.app_label, obj._meta.model_name), args=(child.pk,))
  • 历史页URL: reverse(''admin:{}_{}_history''.format(obj._meta.app_label, obj._meta.model_name), args=(child.pk,))

返回目录

关于django admin启用对计算字段的排序django中admin的问题我们已经讲解完毕,感谢您的阅读,如果还想了解更多关于Django Admin Cookbook-10如何启用对计算字段的过滤、Django Admin Cookbook-15 如何在 Django Admin 后台模型列表页面中添加自定义操作按钮、Django Admin Cookbook-16如何使用Django Admin管理后台导入CSV、Django Admin Cookbook-38如何获取特定对象的Django Admin后台URL等相关内容,可以在本站寻找。

本文标签: