如何设置Django中最高值的排序字段+1的默认值

时间:2022-10-22 17:17:44

Thanks in Advance. I have created a model in Django, in which it has a title, url and an Ordering Field. Now I have set the default value of that Ordering Field as ZERO . My requirement is this defult value should be changed to the current highest Ordering number + 1. Ho can I do that in Admin Inteface?

提前致谢。我在Django中创建了一个模型,它有一个标题,url和一个Ordering Field。现在我已将Ordering Field的默认值设置为ZERO。我的要求是这个defult值应该改为当前最高的订购号+ 1.我可以在Admin Inteface中这样做吗?

class FooterLinks(models.Model):
    title = models.CharField(_("Title"), max_length=200, null = True, blank = True)
    link = models.CharField(_("Link"), max_length = 200)
    order = models.IntegerField(_("Sort Order"), default=0)

2 个解决方案

#1


3  

Inspired by Burhan's answer, I was able to solve a problem of mine, similar to yours.

受到Burhan的回答的启发,我能够解决我的问题,就像你的问题一样。

So for your problem: In my models.py create the callable get_new_default

所以对于你的问题:在我的models.py中创建可调用的get_new_default

from django.db.models import Max

def get_new_default():
    new_order_default = FooterLinks.objects.all().aggregate(Max('order'))['order__max']+1
    return new_order_default

class FooterLinks(models.Model):
    order = models.CharField(_("Sort Order"), default = get_new_default)

This pastes the new maximum order value in the Text Box and keeps the field editable.

这将在文本框中粘贴新的最大订单值,并使该字段可编辑。


---!! Edit !!---

---!编辑!! ---

This raises one problem, when resetting the database, as there are no objects to calculate the maximum with. The fix is to count all the found objects and in case none exist set default to 1:

这在重置数据库时引发了一个问题,因为没有对象来计算最大值。修复是计算所有找到的对象,如果不存在,则将default设置为1:

from django.db.models import Max

    def get_new_default():
        if FooterLinks.objects.all().count() == 0:
            new_order_default = 1
        else:
            new_order_default = FooterLinks.objects.all().aggregate(Max('order'))['order__max']+1
        return new_order_default

    class FooterLinks(models.Model):
        order = models.CharField(_("Sort Order"), default = get_new_default)

#2


2  

from django.db.models import Max
new_default = FooterLinks.objects.all().aggregate(Max('order'))['order__max']+1
FooterLinks.objects.filter(order=0).update(order=new_default)

To make the change permanent, either do a database migration with South; or as danihp suggested override the save method.

要使更改成为永久更改,请使用South进行数据库迁移;或者danihp建议覆盖保存方法。

However note that if you table gets very large, it would be better to implement this logic as a trigger on your database.

但请注意,如果表变得非常大,最好将此逻辑实现为数据库的触发器。

Edit:

No, you would run this one time and it would update all the entries in your database - ideally you would do this during normal system downtime/maintenance windows.

不,您将运行此次并且它将更新数据库中的所有条目 - 理想情况下,您将在正常的系统停机/维护窗口期间执行此操作。

To adjust the value in the text box, you need to update the default that you have given in your model. Note that default can take a value or a callable (in other words, a method). Everytime the field is rendered the method will be called.

要调整文本框中的值,您需要更新模型中给出的默认值。请注意,默认值可以采用值或可调用(换句话说,方法)。每次渲染字段时,都会调用该方法。

You can use this to make sure the default is always calculated by providing a method as the default.

您可以使用它来确保始终通过提供默认方法来计算默认值。

#1


3  

Inspired by Burhan's answer, I was able to solve a problem of mine, similar to yours.

受到Burhan的回答的启发,我能够解决我的问题,就像你的问题一样。

So for your problem: In my models.py create the callable get_new_default

所以对于你的问题:在我的models.py中创建可调用的get_new_default

from django.db.models import Max

def get_new_default():
    new_order_default = FooterLinks.objects.all().aggregate(Max('order'))['order__max']+1
    return new_order_default

class FooterLinks(models.Model):
    order = models.CharField(_("Sort Order"), default = get_new_default)

This pastes the new maximum order value in the Text Box and keeps the field editable.

这将在文本框中粘贴新的最大订单值,并使该字段可编辑。


---!! Edit !!---

---!编辑!! ---

This raises one problem, when resetting the database, as there are no objects to calculate the maximum with. The fix is to count all the found objects and in case none exist set default to 1:

这在重置数据库时引发了一个问题,因为没有对象来计算最大值。修复是计算所有找到的对象,如果不存在,则将default设置为1:

from django.db.models import Max

    def get_new_default():
        if FooterLinks.objects.all().count() == 0:
            new_order_default = 1
        else:
            new_order_default = FooterLinks.objects.all().aggregate(Max('order'))['order__max']+1
        return new_order_default

    class FooterLinks(models.Model):
        order = models.CharField(_("Sort Order"), default = get_new_default)

#2


2  

from django.db.models import Max
new_default = FooterLinks.objects.all().aggregate(Max('order'))['order__max']+1
FooterLinks.objects.filter(order=0).update(order=new_default)

To make the change permanent, either do a database migration with South; or as danihp suggested override the save method.

要使更改成为永久更改,请使用South进行数据库迁移;或者danihp建议覆盖保存方法。

However note that if you table gets very large, it would be better to implement this logic as a trigger on your database.

但请注意,如果表变得非常大,最好将此逻辑实现为数据库的触发器。

Edit:

No, you would run this one time and it would update all the entries in your database - ideally you would do this during normal system downtime/maintenance windows.

不,您将运行此次并且它将更新数据库中的所有条目 - 理想情况下,您将在正常的系统停机/维护窗口期间执行此操作。

To adjust the value in the text box, you need to update the default that you have given in your model. Note that default can take a value or a callable (in other words, a method). Everytime the field is rendered the method will be called.

要调整文本框中的值,您需要更新模型中给出的默认值。请注意,默认值可以采用值或可调用(换句话说,方法)。每次渲染字段时,都会调用该方法。

You can use this to make sure the default is always calculated by providing a method as the default.

您可以使用它来确保始终通过提供默认方法来计算默认值。