允许对django模型进行排序,并提供一个简单的管理界面来重新排序它们。

django-ordered-model的Python项目详细描述


Django订购型号

Build StatusPyPI versioncodecovCode style: black

django有序模型允许对模型进行排序,并提供一个简单的管理 用于重新排序它们的接口。

基于https://djangosnippets.org/snippets/998/https://djangosnippets.org/snippets/259/

请参阅我们的compatability notes,以获得与旧的django和python版本一起使用的适当版本。

安装

$ python setup.py install

您可以使用pip:

$ pip install django-ordered-model

用法

ordered_model添加到SETTINGS.INSTALLED_APPS中。

OrderedModel继承模型以使其有序:

fromdjango.dbimportmodelsfromordered_model.modelsimportOrderedModelclassItem(OrderedModel):name=models.CharField(max_length=100)classMeta(OrderedModel.Meta):pass

模型实例现在有一组方法来相对移动它们。 为了演示这些方法,我们创建了两个实例Item

foo=Item.objects.create(name="Foo")bar=Item.objects.create(name="Bar")

互换头寸

foo.swap(bar)

这将交换两个对象的位置。

在位置上向上移动位置

foo.up()foo.down()

上下移动一个物体只会使它与相邻物体交换位置 物体的正上方或正下方取决于方向。

移动到任意位置

foo.to(12)bar.to(13)

将对象移动到堆栈中的任意位置。这基本上设置了 将值排序为指定的整数。对象介于原始对象和新对象之间 位置按方向增减顺序值 移动。

将对象移动到参考上方或下方

foo.above(bar)foo.below(bar)

将对象直接移动到引用对象的上方或下方,增加或 减小两者之间所有对象的顺序值,具体取决于 移动方向。

移动到堆栈顶部

foo.top()

这会将order值设置为堆栈中的最低值并增加 高于移动对象一的所有对象的顺序值。

移动到堆栈底部

foo.bottom()

这会将order值设置为堆栈中的最高值并减少 低于移动对象1的所有对象的顺序值。

正在更新save()期间将更新的字段

出于性能原因,delete()、to()、below()、above()、top()和bottom() 方法使用django的update()方法更改 由于其中一个调用而被转移。如果模型中的字段 通常在自定义的save()方法中或通过其他应用程序级别进行更新 功能,如datetimefield(auto_now=true),您可以添加其他字段 传递给update()。这只会影响对象的顺序 由于对目标对象而不是目标对象的操作而被移动 对象本身。

foo.to(12,extra_update={'modified':now()}

获取上一个或下一个对象

foo.previous()foo.next()

previous()和next()获取下面正上方的相邻对象 在有序堆栈中,取决于方向。

子集排序

在某些情况下,仅在对象的子集上需要对对象排序。例如, 在多对一/多关系中为用户管理联系人列表的应用程序, 希望允许每个用户订购其联系人,而不管其他用户如何订购 选择他们的顺序。通过order_with_respect_to参数支持此选项。

一个简单的例子如下:

classContact(OrderedModel):user=models.ForeignKey(User,on_delete=models.CASCADE)phone=models.CharField()order_with_respect_to='user'

如果对象相对于多个字段排序,order_with_respect_to支持 定义多个字段的元组:

classModel(OrderedModel)# ...order_with_respect_to=('field_a','field_b')

在多对多关系中,您需要使用从OrderedModel派生的独立直通模型。 例如,管理带有配料的比萨饼的应用程序。

一个简单的例子如下:

classTopping(models.Model):name=models.CharField(max_length=100)classPizza(models.Model):name=models.CharField(max_length=100)toppings=models.ManyToManyField(Topping,through='PizzaToppingsThroughModel')classPizzaToppingsThroughModel(OrderedModel):pizza=models.ForeignKey(Pizza,on_delete=models.CASCADE)topping=models.ForeignKey(Topping,on_delete=models.CASCADE)order_with_respect_to='pizza'classMeta:ordering=('pizza','order')

您还可以为相关模型上的字段指定order_with_respect_to。可以使用以下模型创建一个示例用例:

classItemGroup(models.Model):user=models.ForeignKey(User,on_delete=models.CASCADE)general_info=models.CharField(max_length=100)classGroupedItem(OrderedModel):group=models.ForeignKey(ItemGroup,on_delete=models.CASCADE)specific_info=models.CharField(max_length=100)order_with_respect_to='group__user'

这里的项被放在组中,组中的项使用了一些常规信息,但是项的顺序与项所在的组无关。

当您希望在基类上而不是在各种类的对象的有序列表中的子类上进行排序时,请指定完整的模块pa基类的th:

classBaseQuestion(OrderedModel):order_class_path=__module__+'.BaseQuestion'question=models.TextField(max_length=100)classMeta:ordering=('order',)classMultipleChoiceQuestion(BaseQuestion):good_answer=models.TextField(max_length=100)wrong_answer1=models.TextField(max_length=100)wrong_answer2=models.TextField(max_length=100)wrong_answer3=models.TextField(max_length=100)classOpenQuestion(BaseQuestion):answer=models.TextField(max_length=100)

自定义管理器和查询集

fromordered_model.modelsimportOrderedModelManager,OrderedModelclassItemManager(OrderedModelManager):passclassItem(OrderedModel):objects=ItemManager()

管理集成

若要在“管理更改列表”页中添加箭头以进行重新排序,可以使用 OrderedModelAdminmove_up_down_links字段:

fromdjango.contribimportadminfromordered_model.adminimportOrderedModelAdminfrommodelsimportItemclassItemAdmin(OrderedModelAdmin):list_display=('name','move_up_down_links')admin.site.register(Item,ItemAdmin)

对于多对多关系,您需要以下内联线之一。

OrderedTabularInlineOrderedStackedInline就像django管理员一样。

对于OrderedTabularInline它将如下所示:

fromdjango.contribimportadminfromordered_model.adminimportOrderedTabularInline,OrderedInlineModelAdminMixinfrommodelsimportPizza,PizzaToppingsThroughModelclassPizzaToppingsThroughModelTabularInline(OrderedTabularInline):model=PizzaToppingsThroughModelfields=('topping','order','move_up_down_links',)readonly_fields=('order','move_up_down_links',)extra=1ordering=('order',)classPizzaAdmin(OrderedInlineModelAdminMixin,admin.ModelAdmin):list_display=('name',)inlines=(PizzaToppingsThroughModelTabularInline,)admin.site.register(Pizza,PizzaAdmin)

对于OrderedStackedInline它将如下所示:

fromdjango.contribimportadminfromordered_model.adminimportOrderedStackedInline,OrderedInlineModelAdminMixinfrommodelsimportPizza,PizzaToppingsThroughModelclassPizzaToppingsThroughModelStackedInline(OrderedStackedInline):model=PizzaToppingsThroughModelfields=('topping','order','move_up_down_links',)readonly_fields=('order','move_up_down_links',)extra=1ordering=('order',)classPizzaAdmin(OrderedInlineModelAdminMixin,admin.ModelAdmin):list_display=('name',)inlines=(PizzaToppingsThroughModelStackedInline,)admin.site.register(Pizza,PizzaAdmin)

测试套件

需要Docker。

$ script/test

与django和python的兼容性

django-ordered-model versionDjango versionPython version
3.3.x2.x3.4 and above
3.2.x2.x3.4 and above
3.1.x2.x3.4 and above
3.0.x2.x3.4 and above
2.1.x1.x2.7 to 3.6
2.0.x1.x2.7 to 3.6

维护人员

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
java在字符串中找到一个点?   java如何从dbpedia链接或URL检索XML/RDF数据?   如何在linux上将java程序转换为命令行实用程序?   javaapachecamel使用OnError和ErrorHandlerRef   java Antlr4如何在花费太长时间时停止解析器   无法使用selenium JAVA testcase在JSP页面上单击菜单下拉列表   java实现了一种“静态抽象和可继承”的方法   java无法发回struts2 json插件中的数组   javajavax。jms。JMSException:远程主机强制关闭了现有连接   从数据库和动态选定项检索的java Android Spinner值   java 2 FromUrlEncoded不处理日文字符   java什么使新对象运行这个方法,尽管它不是构造函数?