Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jsp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Django DateTime字段中唯一的月/年组合_Django - Fatal编程技术网

Django DateTime字段中唯一的月/年组合

Django DateTime字段中唯一的月/年组合,django,Django,我有一个DateTimeField,并且喜欢按月/年限制它,即每个月只有一个条目 目前,我使用了两个额外的字段(month/year)与unique\u组合在一起=(“month”、“year”),但肯定有更好的解决方案 class someModel(models.Model): datetime = models.DateTimeField(unique=True) ... class Meta: ordering = ['datetime'] 将

我有一个
DateTimeField
,并且喜欢按月/年限制它,即每个月只有一个条目

目前,我使用了两个额外的字段(
month
/
year
)与
unique\u组合在一起=(“month”、“year”)
,但肯定有更好的解决方案

class someModel(models.Model):
    datetime = models.DateTimeField(unique=True)
    ...

    class Meta:
        ordering = ['datetime']
将通过某个字段值使实例唯一。 这将按月限制:

from django.core.exceptions import ValidationError

class SomeModel(models.Model):
    # Set index to field
    datetime = models.DateTimeField(db_index=True)

    def save(self, *args, **kwargs):
        # If new instance created
        queryset = SomeModel.objects.filter(
                        datetime__startswith=self.datetime.strftime('%Y-%m-'))

        # If instance changed
        if self.id is not None:
            queryset = queryset.exclude(id=self.id)

        if queryset.exists():
            raise ValidationError('Choose another date')

        super(SomeModel, self).save(*args, **kwargs)
将通过某个字段值使实例唯一。 这将按月限制:

from django.core.exceptions import ValidationError

class SomeModel(models.Model):
    # Set index to field
    datetime = models.DateTimeField(db_index=True)

    def save(self, *args, **kwargs):
        # If new instance created
        queryset = SomeModel.objects.filter(
                        datetime__startswith=self.datetime.strftime('%Y-%m-'))

        # If instance changed
        if self.id is not None:
            queryset = queryset.exclude(id=self.id)

        if queryset.exists():
            raise ValidationError('Choose another date')

        super(SomeModel, self).save(*args, **kwargs)
除了现在这样做之外,您不能真正“以本机方式”进行验证,因为在定义模型时,您定义的是DB级验证,并且说MySQL不支持带有年+月唯一约束的DATETIME字段

但是,您可以做的是在字段中添加您自己的验证器,但这将需要在保存/更新模型实例时增加额外的开销。我以前也遇到过datetime/timestamp值的问题,通常年+月唯一约束解决方案是迄今为止最有效/透明的,即使它会增加存储空间(但这是最便宜的元素,对吧?)

但是,如果您决定使用单个字段唯一约束,请参见-您需要向字段添加一个验证器,该验证器检查是否存在具有该年+月组合的其他对象。请注意,在大型系统上,这将是非常低效的,因为MySQL也不支持DATETIME字段上的年/月索引-该值将通过完整表扫描中的函数传递,然后进行过滤:(

您不能真正“本机”执行此操作)除了现在这样做,因为在定义模型时,您定义的是DB级验证,并且说MySQL不支持带有年+月唯一约束的DATETIME字段

然而,您可以做的是在字段中添加您自己的验证器,但这将需要在保存/更新模型实例时增加额外的开销。我以前也遇到过datetime/timestamp值的问题,通常年+月唯一约束解决方案是迄今为止最有效/透明的,即使它会导致额外的存储通用电气(但这是最便宜的元素,对吗?)


但是,如果您决定使用单字段唯一约束,请参阅-您需要在字段中添加一个验证器,以检查是否存在具有该年+月组合的其他对象。请注意,在大型系统上,这将非常低效,因为MySQL也不支持DATETIME字段上的年/月索引-该值将传递给在一个完整的表扫描中对函数进行粗略处理,然后进行过滤:(

事实并非如此,
unique\u for_date
将确保某些字段F在同一日期不会有两次值X。首先,它将允许同一日期的F有不同值(已经打破了OP的要求)第二,这也不是OP想要的。Martin是对的,
unique\u for_date
unique\u for_month
unique\u for_year
在这里不起作用。事实并非如此,
unique\u for_date
将确保某些字段F在同一日期不会有两次值X。首先,它将允许不同的值同一日期F的nt值(已违反OP的要求)第二个问题是day,这也不是OP wantsMartin所说的正确的
unique\u for_date
unique\u for_month
unique\u for_year
在这里不起作用。这是我在回答中提到的字段验证的一个变体。但是u startswith将datetime值转换为字符串并运行一个完整的表扫描。如果你想要一个稍微“黑客”的解决方案,应该可以。这取决于。我刚刚在我的10k行表上测试了它。它完全可以。另外,afaik字段验证器只将它自己的值作为参数,没有id。我肯定可以,但它不会改变查询的复杂性,它仍然是O(n),也就是说,当您的表从10k到100k再到100M增长时,它会变得越来越慢,直到无法忍受为止。如果您对索引运行查询,无论大小,复杂性始终是O(1)。是的,如果您有100M行表,这是一个糟糕的解决方案:)更好地创建额外的密钥。虽然它适用于大多数情况。是的,就像我说的-它应该有效,但在理论上不会扩展-直到OP决定这对他是否重要:)这是我在回答中提到的字段验证的变体。但是_startswith的效率同样低下,因为它将datetime值转换为字符串并运行完整的表扫描。如果你想要一个稍微有点“黑客”的解决方案,这应该是可行的。这要看情况而定。我刚刚在我的10k rows表上测试了它。完全没关系。另外,afaik字段验证器只将它自己的值作为参数,没有id。我肯定是这样,但它并没有改变查询的复杂性,它仍然是O(n),也就是说,随着表从10k到100k再到100M的增长,它会越来越慢,直到无法忍受为止。如果在索引上运行查询,无论大小,复杂性始终为O(1)。是的,如果表中有100万行,这是一个糟糕的解决方案:)最好创建额外的键。不过,这在大多数情况下都是适用的。是的,就像我说的——它应该会起作用,但在理论上不会扩展——直到OP决定这对他是否重要:)