【问题标题】:How to create many-to-one relation with django and to display it in admin interface如何使用 django 创建多对一关系并将其显示在管理界面中
【发布时间】:2011-12-17 18:03:58
【问题描述】:

我有以下问题 - 我想在 django 中创建多对一映射来表示对象和对象片段之间的基本关系,例如:

class Website(models.Model):
    name = models.CharField(max_length = 100)

class WebsiteIp(models.Model):
    website = models.ForeignKey(Website, primary_key = True)
    ip = models.CharField(max_length = 40, primary_key = True)
    introduction_date = models.DateField()

应全部呈现在网站(父对象)编辑页面上。虽然这听起来像微不足道的问题,但我真的找不到任何有用的东西

【问题讨论】:

    标签: python django django-models django-admin


    【解决方案1】:

    将related_name 参数添加到WebsiteIP 上的ForeignKey,如下所示:

    class Website(models.Model):
        name = models.CharField(max_length = 100)
    
    class WebsiteIp(models.Model):
        website = models.ForeignKey(Website, primary_key = True, related_name="IPs")
        ip = models.CharField(max_length = 40)
        introduction_date = models.DateField()
    

    然后,您可以将 IP 引用为来自网站的多对一映射,如下所示:

    website = Website.objects.filter(name="blah")
    if website.count():
      IPs = website[0].IPs
    

    当然未经测试,但这应该会让您朝着正确的方向前进。另请查看:https://docs.djangoproject.com/en/dev/topics/db/models/#many-to-one-relationships

    在你的 admin.py 中,你大概有这样的东西:

    class WebsiteAdmin(admin.ModelAdmin):
      list_display = ('name',)
      search_fields = ['name']
      ordering = ('name', )
    

    更新如下:

    class WebsiteIpInline(admin.TabularInline):
      model = WebsiteIp
      extra = 1
    
    class WebsiteAdmin(admin.ModelAdmin):
      list_display = ('name',)
      search_fields = ['name']
      inlines = ( WebsiteIpInline, )
      ordering = ('name', )
    

    应该显示你想要的!

    【讨论】:

    • 我知道 related_name 会在外键目标对象上创建具有该名称的成员,但我不明白如何使用它来获得在 django 的网站编辑页面上添加/删除/修改 ip 的能力管理员?
    • 它确实显示了一个网站ip的位置,如果我在那里输入一些内容,那么我可以编辑它,但我不能添加多个ip(我假设extra = 1应该意味着“总是为一个创建表单额外的对象进入”?)
    • 您应该可以按+ 符号为IP 创建更多添加表单,或者您可以设置extra = n,其中n 是一个更大的数字。
    • 在我用 IP 填充之前它只显示一个空输入,之后它只允许编辑输入的值(没有额外的输入,没有 + 链接),我怀疑它是数据库结构令人困惑的django(第二个表有复合主键(website_id,ip)),我不能让django管理表结构,因为它是其他应用程序使用的现有数据库(我只想使用django管理其中的数据)。跨度>
    • 你试过设置extra = 5吗?另外,你看到+ 符号了吗?我一直这样做,我没有任何问题。事实上,有时我希望关闭添加新条目的功能。你可以通过设置'max_num = 0'来做到这一点,确保你的内联定义中没有它。
    【解决方案2】:

    解决此问题的方法是修改依赖关系上的主键设置(但这仅在这种情况下有效 - 当有一个键可能对整个表来说是唯一的(在这种情况下为 ip))。

    class WebsiteIp(models.Model):
        website = models.ForeignKey(Website)
        ip = models.CharField(max_length = 40, primary_key = True)
        introduction_date = models.DateField()
    

    在此之后(并且仅在此之后),mkoistinen 提出的部分解决方案将按预期方式工作。一般问题是django通过检查主键列的唯一性(以错误的方式)来检查创建新对象的能力,所以我想也可以通过覆盖一些models.Model方法来解决这个问题,但我没有足够了解 django 内部结构,以便能够指出什么方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-07
      • 1970-01-01
      • 2011-01-27
      • 1970-01-01
      相关资源
      最近更新 更多