2012-06-19 69 views
1

我在django应用程序中有一个表,其中一个字段被称为Order(按排序顺序)并且是一个整数。每次输入新记录时,字段自动增加到下一个数字。我的问题是何时删除一条记录我希望其他记录将数字向上移动,并找不到任何可重新计算表中所有记录的内容,并在记录被删除时向上移动数字。Django/Python中的自动递增字段

例如,表中有5条记录,其中订单号为1,2,3,4和5.有人删除了记录号2,现在我希望数字3,4和5向上移动删除的数字2的地方,所以订单号码现在是1,2,3和4。python,postgres和django可能吗?

在此先感谢!

+0

你为什么要这个?这可能会严重影响外键...... – McKay

+0

@McKay我已经在下面回答说,这个表与任何其他表都没有关系。 fk从哪里来的? – us1415

+1

哦,我发现这个问题是在搜索ID,而你并没有在寻找ID。 – McKay

回答

2

这里是我最终使用:

item.delete() 
items = table.objects.order_by('order') 
count =0 
for element in items: 
    element.order = count 
    element.save() 
    count=count+1 
-1

尝试使用pgadmin在postgres中设置类型sequence的值。

+0

谢谢。当它们中的一个被删除时,它会将这些数字转移吗? – us1415

+0

mmmm ...不,这不是自动增量 – juankysmith

4

你将不得不自己实现这个特性,我非常怀疑一个关系数据库会为你做这件事,并且有很好的理由:这意味着当一行被删除时更新可能的大量行。

您确定需要这个?它可能会变得昂贵。

+0

此表是一个非常小的表,其行数少于10行,并且该字段与任何其他表无关。它的功能是为下拉列表提供排序。 – us1415

+4

如果只是为了排序,为什么你在乎它是否完全顺序?包含缺失项目的序列也可以排序。 –

+0

因为我在屏幕上的列表中显示这个数字,并且不想在屏幕上显示缺少的数字。此外,编辑时,我会显示所有记录,用户将能够更改文本,但订单号码不会更改。 – us1415

0

而不是删除订单 - 你应该创建一个布尔型的字段(无论你喜欢怎么称呼它 - 例如,deleted),并将此字段设置为1以获取“已删除”订单。

与串行字段混淆(这是你的自动增量字段在postgres中调用)将导致后来的问题;特别是如果你有外键和与表的关系。

不仅会影响数据库服务器的性能,它也会影响到您的业务,因为最终您将有两个订单在相同的订单号码周围浮动;即使你已经从数据库中“删除”了一个,订单号码可能已经被其他地方引用了 - 就像你为你的客户打印的收据一样。

+0

就像我对其他答案进行了评论。该字段仅用于对下拉列表进行排序。它与任何其他表格无关,我希望它是干净的,不会遗漏任何中间的序列号。 – us1415

0

您可以尝试使用signals post_save和post_delete查询适当的对象,对它们进行排序,然后查找缺失的数字并根据需要重新指定/保存。对于大量的数据来说这可能相当繁重,但只有少数几乎不会改变的项目,这样可以。

from django.db.models.signals import post_delete 
from django.dispatch import receiver 

def fix_order(sorted_objects): 
    #ensures that the given objects have sequential order values from 1 upwards 
    i = 1 
    for item in sorted_objects 
     if item.order != i: 
      item.order = i 
      item.save() 
     i += 1 

@receiver(post_delete, sender=YourSortedModel) 
def update_order_post_delete(sender, kwargs): 
    #get the sorted items you need 
    sort_items = YourSortedModel.objects.filter(....).order_by('order') 
    fix_order(sort_items) 
1

你可能最好只在表中留下值并使用查询来生成编号。如果您正在编写一些SQL,则可以使用窗口函数来执行此操作。

SELECT 
    output_column, 
    ..., 
    row_number() over (
    order by 
     order_column) 
FROM 
    TheTable; 
0

我碰到这个跑来找别的东西,想点东西出来:

通过在同一个字段存储的顺序表作为你的数据,你失去了数据的完整性,或者如果你索引它,如果你遇到冲突,事情会变得非常复杂。换句话说,有一个bug(或别的东西)很容易给你两个3,一个4,还有其他奇怪的事情会发生。我继承了一个对应用程序至关重要的手动排序顺序的项目(还有其他一些问题),这一直是个问题,只有200-300个项目。

处理手动排序顺序的正确方法是使用单独的表来管理它并使用连接进行排序。这样,您的订单表就会有10个条目,只有它是PK(订单号),并且与您要分类的项目的ID有外键关系。删除的项目将不再有参考。

您可以继续对删除进行排序,与您现在的操作方式类似,您只需将Order模型的FK更新为列表,而不是迭代并重写所有项目。效率更高。

这可以轻松扩展至数百万个手动排序的项目。但不是使用自动递增的整数,你会想给每个项目之间的两个项目之间的一个随机顺序编号,你要把它放在它们之间,并保持足够的空间(几十万应该这样做),所以你可以任意重新编辑,整理它们。

我看到你提到你在这里只有10行,但设计你的架构第一次很好地扩展,作为一种实践,将会让你头痛不已,一旦你养成了习惯它,它不会真的让你有更多的时间。