13

我的 Django 模型有一个名为“updatedOn”的日期时间字段,我需要在此模型上使用库函数来计算一些统计信息,但该函数假定日期时间字段名称为“时间”,以下是该函数如何使用日期时间:

c = qset.filter(time__year=tt.year, time__month=tt.month, time__day=tt.day).count();

在不接触库代码的情况下,如何创建别名“time”来引用“updatedOn”字段,以便使用该功能?

4

4 回答 4

6

我没有对此进行过深入研究,但凭直觉,以下一些方法可能会让您入门。

定制经理

一个自定义管理器get_queryset,在updatedOn过滤time.

自定义字段类型

可以创建一个自定义字段类型,它只作为对另一个字段的引用。

破解 model._meta.fields

模型对象_meta.fields似乎包含该对象中的字段列表。也许您可以尝试添加某种名为 的虚拟字段time,它指的是该updatedOn字段。

于 2013-09-24T17:02:30.523 回答
6

这个旧的Django Snippet为我工作,直到 Django 1.11。正如@Jaberwocky 评论的那样在Django 2.0virtual_only中被删除

但是,弃用警告显示该字段已被弃用private_only但上述链接的删除功能中并未提及这一点。

class AliasField(models.Field):
    # def contribute_to_class(self, cls, name, virtual_only=False):
    #       '''
    #           virtual_only is deprecated in favor of private_only
    #       '''
    #     super(AliasField, self).contribute_to_class(cls, name, virtual_only=True)
    #     setattr(cls, name, self)

    def contribute_to_class(self, cls, name, private_only=False):
        '''
            virtual_only is deprecated in favor of private_only
        '''
        super(AliasField, self).contribute_to_class(cls, name, private_only=True)
        setattr(cls, name, self)

    def __get__(self, instance, instance_type=None):
        return getattr(instance, self.db_column)


class Order(models.Model):
    """
    The main order model
    """
    number = AliasField(db_column='id')
于 2017-10-28T23:42:48.893 回答
3

为模型中的字段创建一个属性:

class MyModel(moels.Model):
    updated_on = models.DateTimeField()

    def _get_time(self):
        return self.updated_on
    time = property(_get_time)
于 2013-09-24T15:47:41.590 回答
2

遵循 miikkas 对 model.Manager 的建议,我想出了以下内容,适用于通过查询 uuid 来检索 id 字段的更简单的情况。该数据库是使用 ID 是用于十六进制字符串的 varchar 字段创建的,并且我正在改装一个顺序整数 ID 字段,因此我可以使用需要它的 Django 的身份验证模块。我想逐步做到这一点,因此黑客。

if DEVELOPMENT['merging_to_sequential_ids_incomplete']:
    class ModelManager(models.Manager):
        def get(self, *args, **kwargs):
            if 'uuid' in kwargs:
                kwargs['id'] = kwargs.pop('uuid')
            return super(ModelManager, self).get(*args, **kwargs)

class Model(models.Model):
    if DEVELOPMENT['merging_to_sequential_ids_incomplete']:
        print >>sys.stderr, 'WARNING: uuid now a synonym to id'
        id = models.CharField(max_length = 32,
            primary_key = True, default = uuid_string)
        objects = ModelManager()  # for Client.objects.get(uuid=...)
        uuid = property(lambda self: self.id)  # for client.uuid
    else:
        id = models.AutoField(primary_key = True)
        uuid = models.CharField(max_length = 32, ...

现在我能:

cd myapp && ../djangopython manage.py shell
WARNING: uuid now a synonym to id
setting up special admin settings
Python 2.7.8 (default, Nov 18 2014, 16:29:10) 
[GCC 4.9.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from myapp.models import *
>>> Client.objects.get(uuid=u'18b86bd7b58e4c0186f7654045ce81d9')
<Client: jc@example.net>
>>> _.uuid
u'18b86bd7b58e4c0186f7654045ce81d9'

filter可以以同样的方式完成。

也许这可以帮助指导其他人寻找一种方法来为 Django 模型字段使用“别名”或“同义词”。我不相信它会帮助OP。自定义字段类型可能是更好的通用方法。

于 2015-01-26T08:02:48.997 回答