【问题标题】:Django admin foreign key dropdown with custom value带有自定义值的 Django 管理外键下拉列表
【发布时间】:2013-10-24 09:29:58
【问题描述】:

我有 3 个 Django 模型:

class Test(models.Model):
    pass

class Page(models.Model):
    test = models.ForeignKey(Test)

class Question(model.Model):
    page = models.ForeignKey(Page)

如果我将Question 模型注册到管理员,我会得到一个带有所需Page 的下拉列表。现在,我需要修改什么来显示所需的Page plus 该页面对应的Test

假设我创建了三个页面,下拉列表将包含以下值:Page1Page2Page3。我想看看:Page1 - Test1Page2 - Test1Page3 - Test1

【问题讨论】:

  • 你想在管理员列表页面中显示这个吗?
  • 我想在问题添加/编辑页面中显示这个。

标签: python django django-admin


【解决方案1】:

由于某种原因,已接受答案中的选项 B 对我不起作用,所以我想我会用适合我的方法更新此页面。

您可以为 Page 模型重载 __str__ 函数以获得您想要的。所以,类似这样的事情

class Page(models.Model):
   test = models.ForeignKey(Test)
   def __str__(self):
      return f'Page{self.pk} - Test{self.test.pk}'

【讨论】:

  • 这个答案被否决的原因是它建议普遍覆盖模型实例的字符串表示。我相信这个问题意味着他们只希望在 admin/ 中自定义字符串表示
【解决方案2】:

2 个选项。

选项 1:

创建一个新的field,复制forms.ModelChoiceField 并覆盖label_from_instance

# From the source
class PageModelChoiceField(forms.ModelChoiceField():
    def label_from_instance(self, obj):
        """
        This method is used to convert objects into strings; it's used to
        generate the labels for the choices presented by this object. Subclasses
        can override this method to customize the display of the choices.
        """
        # Then return what you'd like to display
        return "Page{0} - Test{1}".format(obj.pk, obj.test.pk)

这只会更改该特定下拉字段的文本。当您访问列表中每个项目的Test 对象时,您可能希望确保传递给PageModelChoiceFieldqueryset 具有select_related('test'),否则它将对列表中的每个项目进行数据库命中.

我没有测试过这个确切的代码,但逻辑是存在的。以后有空再试试吧

class QuestionForm(forms.ModelForm):

    page = PageModelChoiceField(
        queryset=Page.objects.select_related('test').all()
    )

    class Meta:
        model = Page


class QuestionAdmin(ModelAdmin):
    class Meta:
        model = Question
        form = QuestionForm

选项 B。

更改Pageunicode() 表示。

class Page(models.Model):
    test = models.ForeignKey(Test)

    def __unicode__(self):
        return "Page{0} - Test{1}".format(obj.pk, obj.test.pk)

这将改变Pages 在您打印页面对象print(page_object){{ page_object }} 的所有位置的显示方式。


我个人更喜欢选项 1

【讨论】:

  • 感谢您的详细解答!
  • 乐于助人。我总是更喜欢完整的答案,所以我认为最好自己也提供:)
  • 谢谢.. 选项 B 让我很开心.. 使用 'self.' 而不是 'obj.pk'
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-12
  • 2021-11-01
  • 1970-01-01
  • 2012-02-25
  • 2012-10-05
相关资源
最近更新 更多