格式化 django admin 中呈现的内联多对多相关模型

发布于 2024-09-03 03:09:42 字数 831 浏览 5 评论 0原文

我有两个 django 模型(简化):

class Product(models.Model):
    name  = models.TextField()
    price = models.IntegerField()

class Invoice(models.Model):
    company  = models.TextField()
    customer = models.TextField()
    products = models.ManyToManyField(Product)

我希望在管理的发票页面中将相关产品视为一个漂亮的表格(产品字段),并能够链接到各个产品产品页面。

我的第一个想法是使用管理员的内联 - 但 django 对每个相关产品使用了一个选择框小部件。这没有链接到产品页面,而且由于我有数千个产品,并且每个选择框都独立下载所有产品名称,因此它很快就会变得不合理的慢。

所以我按照建议转向使用 ModelAdmin.filter_horizo​​ntal 这里,它使用了不同小部件的单个实例,其中您有一个所有产品的列表和另一个相关产品的列表,您可以在前者中添加/删除后者的产品。这解决了缓慢的问题,但它仍然没有显示相关的产品字段,并且它不可链接。

那么,我该怎么办?调整视图?覆盖模型表单?我用谷歌搜索了一下,找不到任何此类代码的示例......

I've got two django models (simplified):

class Product(models.Model):
    name  = models.TextField()
    price = models.IntegerField()

class Invoice(models.Model):
    company  = models.TextField()
    customer = models.TextField()
    products = models.ManyToManyField(Product)

I would like to see the relevant products as a nice table (of product fields) in an Invoice page in admin and be able to link to the individual respective Product pages.

My first thought was using the admin's inline - but django used a select box widget per related Product. This isn't linked to the Product pages, and also as I have thousands of products, and each select box independently downloads all the product names, it quickly becomes unreasonably slow.

So I turned to using ModelAdmin.filter_horizontal as suggested here, which used a single instance of a different widget, where you have a list of all Products and another list of related Products and you can add\remove products in the later from the former. This solved the slowness, but it still doesn't show the relevant Product fields, and it ain't linkable.

So, what should I do? tweak views? override ModelForms? I Googled around and couldn't find any example of such code...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

南风起 2024-09-10 03:09:42

也许这不是您所期望的,但我将介绍 InvoiceItem 模型,它将发票链接到产品。所以你会得到 2x 1:n 而不是 m:n 关系。然后使用 InvoiceItem 的内联自定义表单,并在该表单中使用 raw_id_fields 进行产品选择。

在 InvoiceItem 表单中,您可以添加只读字段来显示您需要显示的值。您必须在 Form 的 init 中提供这些字段的数据,并从 InvoiceItem 实例中读取它们。或者您也可以从 raw_id_field 小部件派生并在该小部件的渲染方法中附加来自产品模型的一些附加数据?

Maybe it is not what you expect but I would introduce InvoiceItem model which would link Invoice to Product. So you would have 2x 1:n instead of m:n relation. Then use inline custom form for InvoiceItem and raw_id_fields in that form for Product choice.

In InvoiceItem form then you could add readonly fields that would display values you need to display. You will have to provide data for these fields in Form's init reading them from InvoiceItem instance. Or you could also derive from raw_id_field widget and in render method of this widget append some additional data from the product model?

往事风中埋 2024-09-10 03:09:42

这是一个老问题了,但我今天就涉及到了。

您可以在这里找到答案 - https: //blog.ionelmc.ro/2012/01/19/tweaks-for-making-django-admin-faster/

代码:

class MyAdmin(admin.TabularInline):
    fields = 'myfield',
    def formfield_for_dbfield(self, db_field, **kwargs):
        formfield = super(MyAdmin, self).formfield_for_dbfield(db_field, **kwargs)
        if db_field.name == 'myfield':
            # dirty trick so queryset is evaluated and cached in .choices
            formfield.choices = formfield.choices
        return formfield

这可以将您的等待时间从 5 分钟缩短到大约 15 秒。

This is an old question, but I have related to it today.

You can find the answer here - https://blog.ionelmc.ro/2012/01/19/tweaks-for-making-django-admin-faster/

The code:

class MyAdmin(admin.TabularInline):
    fields = 'myfield',
    def formfield_for_dbfield(self, db_field, **kwargs):
        formfield = super(MyAdmin, self).formfield_for_dbfield(db_field, **kwargs)
        if db_field.name == 'myfield':
            # dirty trick so queryset is evaluated and cached in .choices
            formfield.choices = formfield.choices
        return formfield

This can cut your waiting times from anything like 5 minutes to around 15 seconds.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文