2012-03-28 215 views
3

在我的应用程序中,我定义了一个自定义字段来表示使用quantities包的物理量。自定义排序在Django的自定义字段中

class AmountField(models.CharField): 
    def __init__(self, *args, **kwargs): 
     ... 

    def to_python(self, value): 
     create_quantities_value(value) 

本质上,它的工作方式是它延伸CharField的值存储在数据库中的

"12 min" 

一个字符串,其表示为批量使用领域模型时对象

array(12) * min 

然后,在模型它被用作这样:

class MyModel(models.Model): 
    group = models.CharField() 
    amount = AmountField() 

    class Meta: 
     ordering = ['group', 'amount'] 

我的问题是这些字段似乎不是按数量排序,而是按字符串排序。

所以,如果我有包含类似

  • 一些对象{ “基团”: “A”, “量”: “12分钟”}
  • { “基团”: “A”, “数量”:“20分钟”}
  • {“group”:“A”,“amount”:“2min”}
  • {“group”:“B”,“amount”:“20min” }
  • {“group”:“B”,“amount”:“1 hr”}

他们最终排序如下:

>>> MyModel.objects.all() 
[{A, 12 min}, {A, 2 min}, {A, 20 min}, {B, 1 hr}, {B, 20 min}] 

基本上按字母顺序。

我可以给我的自定义AmountField一个比较函数,以便它可以通过python值而不是DB值进行比较吗?

回答

0

您可以将它与前导零存储在数据库中吗?

E.g. “02分”

这样它会正确排序,当你再次解析它时,前导零应该无关紧要。

+0

这不是一个真正的选择。首先,我使用[quantity](http://packages.python.org/quantities/user/tutorial.html)对象的字符串表示形式,并且不必编辑该代码。即使我做了,也会有未知数量的前导零。我用它来存储不只是时间,而是任何东西。例如,可能是10000磅。 – RotaJota 2012-03-28 17:04:55

1

我认为没有办法将它排序为数字。我的意思是没有有效的方法,因为我相信Django允许以某种方式通过计算领域进行排序,但是您必须计算所有键来执行此操作。因此,尽量找到一种方法将数字作为数字存储在数据库中。也许将数量存储为整数并添加方法或属性以将其转换为数量对象?类似这样的:

class MyModel(models.Model): 
    group = models.CharField() 
    amount = models.IntegerField() # or PositiveIntegerField 

    class Meta: 
     ordering = ['group', 'amount'] 

    def amountAsQuantityObject(self): 
     return create_quantities_value(self.amount) 

    # or as a property 
    quantity_object = property(amountAsQuantityObject) 
+0

在这种情况下,是否有可能在数据库中有一个自定义的django字段存储为两列(一列为金额,一为单位)?即使那样,我想能够比较python对象,因为这不允许在不同单位(分钟和小时,例如)之间进行比较。 – RotaJota 2012-03-28 17:49:45

+0

有一个[ticket](https://code.djangoproject)。 com/ticket/5929)关于多列字段。作为一种解决方法:您可以使用[pickle](http://docs.python.org/library/pickle.html)模块序列化数量对象。这不是很舒服,但如果你想要有效的分类,你必须为一种资源(时间,体重等)选择一个测量单位。 – Kirill 2012-03-28 18:04:58

+1

我想知道你是不是让自己变得不必要的困难。我知道你更喜欢做一个Python排序,但是这要求你先将数据库中的所有内容加载到内存中,然后再进行排序。我还强烈建议不要将相同类型(时间,距离,重量)的不同单位存储在数据库中,只是将所有内容存储为例如分钟和工作。 – knabar 2012-03-28 18:15:29

0

我打算采用完全不同的方法。

而不是有一个自定义字段来存储什么是真正的时间单位,为什么不只是存储时间单位?

例如,02分钟,应该只是02.您可以存储为整数,或者我认为有一个TimeField可以让您以单位时间存储单位。

你显然希望它显示,以便人类可以正确理解02真的意味着2分钟,所以只需在窗体中编写一个自定义过滤器来处理分钟或小时或任何你可能想要添加到结尾。

这会带来其他好处。假设您想添加以前的所有时间单位。为此,需要进行一些字符串处理,并将该字符串部分更改为具有的地址,或者添加的子地址或类似的方法。