【问题标题】:Dynamical choices in model's field模型领域的动态选择
【发布时间】:2012-12-23 10:00:17
【问题描述】:

我希望我的模型有 order 字段,它将包含一个项目在所有同类项目中的顺序。

我想在 IntegerField 中使用 choices,它将包含该表中当前存在的所有项目的数量。

因此需要动态选择。

如何加载表中所有现有项目的所有现有“订单”值,并使用此列表进行选择?

【问题讨论】:

  • 查看this问题并检查danihp给出的答案
  • 如果我能以任何方式理解它的作用,也许我会使用它。

标签: django django-models


【解决方案1】:

听起来你想为你的模型建立一个管理器:

models.py

from django.db import models


class OrderManager(models.Manager):

    def order_choices(self):
        return [(i, i) for i in OrderModel.objects.values_list('order', flat=True)]


class OrderModel(models.Model): 

    objects = OrderManager()
    order = models.IntegerField()

    class Meta:
        ordering = ['order'] 

    def __unicode__(self):
        return '%i' % self.order

forms.py

from django import forms

from yourapp.models import OrderModel


class OrderModelForm(forms.ModelForm):
    order = forms.ChoiceField(choices=OrderModel.objects.order_choices())

    class Meta:
        model = OrderModel

admin.py

from django.contrib import admin

from yourapp.forms import OrderModelForm
from yourapp.models import OrderModel


class OrderModelAdmin(admin.ModelAdmin):

    form = OrderModelForm


admin.site.register(OrderModel, OrderModelAdmin)

编辑

管理器用于在没有模型对象实例的情况下进行一般模型查询。如果您不了解管理器的概念,您仍然可以从管理器类中重构代码,将其粘贴到其他地方并在您的代码中导入该函数。管理器允许您抽象出可以重用的自定义通用查询集。查看更多详情https://docs.djangoproject.com/en/dev/topics/db/managers/

没有管理器的代码看起来像

views.py 或其他文件

from app.models import OrderModel

def order_choices():
    return [(i, i) for i in OrderModel.objects.values_list('order', flat=True)]

如果您想多次重复使用上述代码,可以从代码中的任何位置:

from app.views import oder_choices

order_choices()

相对于:

from app.models import OderModel

OrderModel.objects.order_choices()

如果您只想使用上述一次,您可以将其留在forms.py 中,如另一个答案所示。如何重构代码完全取决于您。

【讨论】:

  • 我了解 forms.py 和 admin.py,但为什么(在此解决方案中)我需要自定义管理器?仅使用自定义表单难道不能实现我想要的吗?如果我想按“订单”值订购商品,我可以在没有经理的情况下这样做,不是吗?
  • 我认为您想要一种从模型中找到该列表的方法,就像您之前的评论中解释了管理器的使用一样。如果原意发生变化,您可以重新澄清您的问题,以便我们正确回答。
  • 是的,我确实想从数据库中所有当前存在的模型中加载/创建 CHOICES 列表。但是,我只需要表单中选择框中的此信息。 (或者在模型本身的可能选择中,因此它在模型级别而不是表单级别上正确验证 - 甚至更好)。但是,如果我使用自定义表单来实现这一点 - 所以我在我的选择框中获得了所需的值,那么经理的含义是什么?请详细说明您的解决方案,我有点迷茫。我赞成它,但我不完全理解它。
  • 我认为这可以在没有任何经理的情况下完成。我在一定程度上理解经理,但我可以简单地使用列表理解加载选择选项:CHOICES = [(item.order, item.order) for item in MyModel.objects.all()]
  • 这就是为什么我问为什么我已经需要创建自定义表单时还需要经理。py
【解决方案2】:

不要将选项直接添加到模型中,稍后通过使用一组选项覆盖字段来将它们添加到代表模型的表单中。

然后,做类似的事情:

class MyForm(..):
    myfield_order_field = IntegerField(choices = [(i,i) for range(MyModel.objects.count)])
    class Meta():
        model = MyModel

如果您想在管理员中使用它,请添加到您的管理员类:

class MyModelAdmin(admin.ModelAdmin):
...

    form = MyForm

它也会覆盖管理员中的这个字段。

【讨论】:

  • 我明白,但我希望选择字段也可以在管理员中使用。因此,我认为在模型中正确地进行操作是可行的方法。
  • 但是有没有办法从模型定义中调用 Model.objects.all() ?是否可以从模型中获取该列表?如果我没有找到其他方法,我会接受这个。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-12-20
  • 1970-01-01
  • 2014-01-05
  • 2021-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多