django foreignkey通过相关_名称访问

django foreignkey通过相关_名称访问,django,Django,从我所读到的和这里的一些帖子(以及阅读他们的解决方案)中,我认为我实现了这个正确的方法。看来我还没有完全掌握外键和相关名称。下面是我的模型以及我为了访问链接类所做的工作 class Menu(models.Model): menu_name = models.CharField(max_length=25, verbose_name="Menu Name") urlconf_name = models.CharField(max_length=25, verbose_name="

从我所读到的和这里的一些帖子(以及阅读他们的解决方案)中,我认为我实现了这个正确的方法。看来我还没有完全掌握外键和相关名称。下面是我的模型以及我为了访问链接类所做的工作

class Menu(models.Model):
    menu_name = models.CharField(max_length=25, verbose_name="Menu Name")
    urlconf_name = models.CharField(max_length=25, verbose_name="URLConf Name")
    menu_position = models.IntegerField(verbose_name="Menu Position", unique=True)
    has_sub_menu = models.BooleanField(default=False, verbose_name="Sub Menu Linked")
    active = models.BooleanField(default=True, verbose_name="Menu Active")

    def __str__(self):
        return self.menu_name

class Sub_Menu(models.Model):
    class Meta:
        ordering = ['menu_position']
    sub_name = models.CharField(max_length=25, verbose_name="Sub Menu Name")
    urlconf_name = models.CharField(max_length=25, verbose_name="Sub Menu URLConf Name")
    menu_position = models.IntegerField(verbose_name="Sub Menu Position")
    menu_id = models.ForeignKey(Menu, related_name="submenu")
    active = models.BooleanField(default=True, verbose_name="Menu Active")

    def __str__(self):
        return self.sub_name
现在我想我可以简单地使用something.子菜单(即相关的名称)访问链接的数据,但它似乎不起作用。用上面的代码,我已经试过了

the_menu = Menu.objects.filter(urlconf_name=split_path[0])
built_breadcrumb.append([the_menu[0].menu_name, split_path[0]])
if the_menu[0].has_sub_menu:
    built_breadcrumb.append([the_menu[0].submenu.sub_name, the_menu[0].submenu.urlconf_name])
那不行。我刚刚意识到它将返回一个项目列表,但我仍在努力解决如何访问它们。我也试过

the_menu[0].submenu.filter(urlconf_name='home/contactus')
这也是一个错误

我绞尽脑汁想让别人解释一下如何通过相关的名称访问我真的很感激。我已经这样做了(通过在这里帮助某人),但出于某种原因,在这种情况下它似乎不起作用

非常感谢

韦恩

主要问题 事实(从您的模型中读取):

  • 一个菜单可以与多个子菜单相关
  • 子菜单可以与一个菜单相关
记住这一点,请再次阅读这一行:

built_breadcrumb.append([the_menu[0].submenu.sub_name, the_menu[0].submenu.urlconf_name])
本部分具体如下:

the_menu[0].submenu.sub_name
子菜单
是一个查询集,因此需要对其进行处理。换句话说:“获取哪个子菜单的子菜单名?”

附加问题
.filter
返回一个查询集,
.get
返回一个对象,因此您可能需要如下内容:

the_menu = Menu.objects.get(urlconf_name=split_path[0])
if the_menu.submenus.count() > 0:
    ....
现在,
u菜单
包含对一个菜单的引用,因此您可以在后面的几行中松开它后面的
[0]

第二个问题(不是真的,但有误导性) 不要调用您的字段
菜单\u id
,此处:

class Sub_Menu(models.Model):
    ....
    menu_id = models.ForeignKey(Menu, ...)
原因如下:

the_menu = submenu.menu_id 
# the_menu is now an instance of a Menu class, not an ID

the_menu_id = submenu.menu_id.id  # the_menu_id is now an ID (integer)
# or:
the_menu_id = submenu.menu_id_id  # the_menu_id is now an ID (integer)
我建议有一种不太容易混淆的方式来命名字段:

class Sub_Menu(models.Model):
    ....
    menu = models.ForeignKey(Menu, ...)
现在,与上面的示例相同:

the_menu = submenu.menu 
# the_menu is now an instance of a Menu class, not an ID

the_menu_id = submenu.menu.id  # the_menu_id is now an ID (integer)
# or:
the_menu_id = submenu.menu_id  # the_menu_id is now an ID (integer)
请求
.menu
并获得
菜单是有意义的
要求
.menu\u id
并获得
菜单
是没有意义的

Django在内部创建一个字段来保存外键的ID,并通过在字段名中添加“\u ID”来命名它,因此在第一个示例中为
menu\u ID\u ID
,在第二个示例中为
menu\u ID

附加旁注(假设更新的字段名):
菜单.menu.id
将弹出
子菜单.DoesNotExist
,而
菜单.menu.id
仅返回
。如果直接使用
菜单id
的话,这只是需要注意的东西

同样,这是假定更改了字段名。如果不是这样,只需添加一个
\u id

好吧,让我们重做这一批。。。 注意这些变化:

  • 菜单
    ,而不是
    菜单id
  • 子菜单
    ,而不是
    子菜单
  • 好的,现在名称与实际引用的名称匹配

    try:
        the_menu = Menu.objects.get(urlconf_name=split_path[0])
    except Menu.DoesNotExist:
        # what to do if menu does not exist?
        return # or raise or something...
    built_breadcrumb.append([the_menu.menu_name, split_path[0]])
    if the_menu.has_sub_menu:  # this line is now probably not needed, just remove it and go straight to the for loop (of course, un-indent the for loop)
        for submenu in the_menu.submenus.filter(active=True):  # I added .filter(active... But if wanna go over all the submenus regardless of 'active', then use .all() instead of .filter(...)
            built_breadcrumb.append([submenu.sub_name, submenu.urlconf_name])
    
    这会让你走上正确的轨道

    哦,等等,你想要一对一的关系吗? 在写我的答案时,我突然想到,您可能希望在菜单类和子菜单类之间建立一对一的关系。如果是这种情况,则任务的
    ForeignKey
    工具是错误的。相反,你应该退房。以下是该方法的工作原理:

    class Menu(models.Model):
        ...
    
    class Sub_Menu(models.Model):
        sub_name = models.CharField(max_length=25, verbose_name="Sub Menu Name")
        menu = models.OneToOneField(Menu, related_name="submenu")
        ...
    
    
    try:
        the_menu = Menu.objects.get(urlconf_name=split_path[0])
    except Menu.DoesNotExist:
        # what to do if menu does not exist?
        return # or raise or something...
    built_breadcrumb.append([the_menu.menu_name, split_path[0]])
    try:
        built_breadcrumb.append([the_menu.submenu.sub_name, the_menu.submenu.urlconf_name])
    except SubMenu.DoesNotExist:
        # what to do it there is no submenu
        pass  # probably nothing, just move on
    
    最后说明 无论如何,我认为您不需要
    has\u sub\u menu
    字段,因为您可以从其他字段获取该信息。对于1对1关系,上面显示了try-except块。对于一对多(即外键)关系,
    for
    循环根本不会做任何事情。或者,如果您确实需要,您可以像这样使用
    .count

    the_menu = Menu.objects.get(urlconf_name=split_path[0])
    
    if the_menu.submenus.count() > 0:
        ....
    
    但是请记住,这是对数据库的额外打击,可能没有必要(因此应该不鼓励这样做)。

    主要问题 事实(从您的模型中读取):

    • 一个菜单可以与多个子菜单相关
    • 子菜单可以与一个菜单相关
    记住这一点,请再次阅读这一行:

    built_breadcrumb.append([the_menu[0].submenu.sub_name, the_menu[0].submenu.urlconf_name])
    
    本部分具体如下:

    the_menu[0].submenu.sub_name
    
    子菜单
    是一个查询集,因此需要对其进行处理。换句话说:“获取哪个子菜单的子菜单名?”

    附加问题
    .filter
    返回一个查询集,
    .get
    返回一个对象,因此您可能需要如下内容:

    the_menu = Menu.objects.get(urlconf_name=split_path[0])
    
    if the_menu.submenus.count() > 0:
        ....
    
    现在,
    u菜单
    包含对一个菜单的引用,因此您可以在后面的几行中松开它后面的
    [0]

    第二个问题(不是真的,但有误导性) 不要调用您的字段
    菜单\u id
    ,此处:

    class Sub_Menu(models.Model):
        ....
        menu_id = models.ForeignKey(Menu, ...)
    
    原因如下:

    the_menu = submenu.menu_id 
    # the_menu is now an instance of a Menu class, not an ID
    
    the_menu_id = submenu.menu_id.id  # the_menu_id is now an ID (integer)
    # or:
    the_menu_id = submenu.menu_id_id  # the_menu_id is now an ID (integer)
    
    我建议有一种不太容易混淆的方式来命名字段:

    class Sub_Menu(models.Model):
        ....
        menu = models.ForeignKey(Menu, ...)
    
    现在,与上面的示例相同:

    the_menu = submenu.menu 
    # the_menu is now an instance of a Menu class, not an ID
    
    the_menu_id = submenu.menu.id  # the_menu_id is now an ID (integer)
    # or:
    the_menu_id = submenu.menu_id  # the_menu_id is now an ID (integer)
    
    请求
    .menu
    并获得
    菜单是有意义的
    要求
    .menu\u id
    并获得
    菜单
    是没有意义的

    Django在内部创建一个字段来保存外键的ID,并通过在字段名中添加“\u ID”来命名它,因此在第一个示例中为
    menu\u ID\u ID
    ,在第二个示例中为
    menu\u ID

    附加旁注(假设更新的字段名):
    菜单.menu.id
    将弹出
    子菜单.DoesNotExist
    ,而
    菜单.menu.id
    仅返回
    。如果直接使用
    菜单id
    的话,这只是需要注意的东西

    同样,这是假定更改了字段名。如果不是这样,只需添加一个
    \u id

    好吧,让我们重做这一批。。。 注意这些变化:

  • 菜单
    ,而不是
    菜单id
  • 子菜单
    ,而不是
    子菜单
  • 好的,现在名称与实际引用的名称匹配

    try:
        the_menu = Menu.objects.get(urlconf_name=split_path[0])
    except Menu.DoesNotExist:
        # what to do if menu does not exist?
        return # or raise or something...
    built_breadcrumb.append([the_menu.menu_name, split_path[0]])
    if the_menu.has_sub_menu:  # this line is now probably not needed, just remove it and go straight to the for loop (of course, un-indent the for loop)
        for submenu in the_menu.submenus.filter(active=True):  # I added .filter(active... But if wanna go over all the submenus regardless of 'active', then use .all() instead of .filter(...)
            built_breadcrumb.append([submenu.sub_name, submenu.urlconf_name])
    
    这会让你走上正确的轨道

    哦,等等,你想要一对一的关系吗? 在写我的答案时,我突然想到,您可能希望在菜单类和子菜单类之间建立一对一的关系。如果是这样的话,那么