Django/Wagtail中的大型嵌套层次结构:育儿还是分类



我有一个数据库,其中包含50000种药物的元数据,这些药物是按层次排序的(分类法称为ATC(。心脏药物示例如下:

  • A
  • --A10
  • ----A10X,美托洛尔

有些药物有4个水平。

我需要为每种药物生成一个单独的页面。在wagtail/django中,最有效的方法是什么,包括考虑到用户想要一种简单直观的方式来搜索数据库。

我尝试过django-mptt,定义了以下模型。

class ATCChapter(MPTTModel): # MAIN CHAPTER
    chapter_letter = models.CharField(max_length=255, null=True, blank=True) # E.g "A"
    chapter_title = models.CharField(max_length=255, null=True, blank=True) # E.g "Cardiac drugs"
    parent = TreeForeignKey('self', on_delete=models.CASCADE, null=True, blank=True, related_name='children')
    class MPTTMeta:
        order_insertion_by = ['chapter_letter']
class ATCSubchapter(MPTTModel): # SUBCHAPTER
    subchapter_letter = models.CharField(max_length=255, null=True, blank=True) # E.g "A10"
    subchapter_title = models.CharField(max_length=255, null=True, blank=True) # E.g "Drugs used in heart failure"
    parent = TreeForeignKey(ATCChapter, on_delete=models.CASCADE, null=True, blank=True, related_name='subchapter')
    class MPTTMeta:
        order_insertion_by = ['subchapter_letter']
class ATCDrug(MPTTModel, Page): # INDIVIDUAL DRUG
    drug_code = models.CharField(max_length=255, null=True, blank=True) # E.g "A10X"
    drug_name = models.CharField(max_length=255, null=True, blank=True) # E.g "Metoprolol"
    parent = TreeForeignKey(ATCSubchapter, on_delete=models.CASCADE, null=True, blank=True, related_name='disease')
    class MPTTMeta:
        order_insertion_by = ['drug_code']

进行迁移会引发以下错误:class ATCDrug(MPTTModel, Page): TypeError: metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases

这可以通过不让类从Page继承来解决,这当然是不好的。我删除了Page并试用了模型,但无法验证父子方案是否正确。

问题:我是在做明显错误的事情,还是在目标下做得不理想。

系统:Wagtail 2.10,Postgresql,计划使用Algolia进行搜索。

感谢您的建议。

根据您的要求,每种药物都用一个页面表示,如果您确实打算在中长期使用Wagtail,我建议每种药物使用page模型。

这是因为你将获得所有的好处,能够向用户展示这一点,提供搜索,API和用户界面编辑功能,而没有任何麻烦。

但是,下一个决定是将所有这些放在一个父页面模型下,还是将层次结构存储在页面模型中。

如果你知道层次结构在精确的五个深度级别上是非常严格的,并且每个深度都有一个特定的名称和商定的定义,那么最好将这些"级别"编码到模型中。请注意,每个药物页面的url将默认为url.com/level-1/level2-/..../insulin,而不是类似url.com/medications/insulin的内容。

然而,通过RoutablePageMixin也可以很容易地在Url树中的某个固定(非嵌套(点提供每个药物。然而,如果您希望规范URL是这种非嵌套的变体,您可能会发现自己在与Wagtail进行少量的斗争。这样做的好处是,您可以通过内置的页面资源管理器(管理菜单(进行导航,在树的右点找到Insulin页面。

反过来说,将层次结构存储为页面模型可能仍然值得,但药物页面模型本身将是其他中心页面的子页面。这为每种药物提供了更简单的规范URL,但也意味着每个级别的Page都可以使用RoutablePageMixin来访问其子代。这种方法的缺点是,管理员编辑界面不会直接反映药物页面的层次结构。

然而,在50000个条目的情况下,编辑交互无论如何都需要一些调整和替代方法来找到页面。

例如

  • 主页
  • 。。。级别
  • 。。。。。。A1(等(
  • 。。。药物
  • 。。。。。。胰岛素
  • 联系人(其他杂项页面也在主页下(

这里可能没有一个"正确"的答案,你可能会发现最好设置一些程序化的页面创建&链接(或类似于fixture的东西(,只需双管齐下,并在您的beta Wagtail实例中设置两个站点。通过这种方式,您可以看到编辑的感觉,给您的团队一个比赛的机会,还可以设置API。最后,无论哪种方式,您最终都需要在页面模板和模型方面非常相似的代码。

最新更新