【问题标题】:add link to change page using raw_id_fields in django admin在 django admin 中使用 raw_id_fields 添加链接以更改页面
【发布时间】:2016-06-29 14:34:03
【问题描述】:

是否有机会在 django admin 中的“raw_id_fields”旁边添加链接以更改外键对象的页面? 我使用 raw_id_fields 来减少对 mysql 的查询次数。 当我不使用 raw_id_fields 时,我可以编辑或添加外键对象。

如何使用 raw_id_fields?

@AntoinePinsard,我尝试了第二种解决方案。 “Edit My FK”字段已创建,但除了连字符外什么都没有。

那是我的模型管理员。

class FlatAdmin(admin.ModelAdmin):
    inlines = [NeedInline]
    readonly_fields = ('flat_house_edit_link',)
    raw_id_fields = ('flat_house',)
    list_display = ('show_date','show_block','show_house','show_rooms','show_price','show_stage')
    list_filter = ('flat_house__house_block','flat_rooms')
    search_fields = ('flat_house__id',)

    field = ['flat_house','flat_house_edit_link','flat_owner','flat_price','flat_rooms','flat_total_sq','flat_life_sq','flat_kitchen_sq','flat_floors']

    def flat_house_edit_link(self, instance):
        if instance:
            fk_id = instance.user_id
        else:
            fk_id = None
        if fk_id:
            opts = instance._meta.get_field('flat_house').rel.model._meta
            related_url = reverse(
                'admin:{}_{}_change/?_to_field=id&_popup=1'.format(
                     opts.ha,
                     opts.house,
                ),
                args=[fk_id],
            )
            return format_html(
                 '<a target=_blank href="{}">Go!</a>', related_url)
        else:
            return "No related object"
    flat_house_edit_link.short_description = "Change house"
admin.site.register(Flat,FlatAdmin)

【问题讨论】:

    标签: django django-admin


    【解决方案1】:

    注意此行为现在是built-in since Django 1.10

    您可以创建自定义小部件来根据需要呈现此字段。

    from django.contrib.admin.widgets import ForeignKeyRawIdWidget
    from django.core.urlresolvers import reverse, NoReverseMatch
    from django.utils.html import format_html
    
    class ForeignKeyLinkedRawIdWidget(ForeignKeyRawIdWidget):
        def render(self, name, value, attrs=None):
            output = super().render(name, value, attrs)
            try:
                related_url = reverse(
                    'admin:{}_{}_change'.format(
                        self.rel.model._meta.app_label,
                        self.rel.model._meta.model_name,
                    ),
                    args=[value],
                )
            except NoReverseMatch:
                return output
            return format_html('{output} <a href="{url}">edit</a>',
                               output=output, url=related_url)
    

    在你的表单中使用这个小部件,而不是使用raw_id_fields

    from myapp.forms.widgets import ForeignKeyLinkedRawIdWidget
    
    class MyForm(forms.ModelForm):
        class Meta:
            model = MyModel
            fields = '__all__'
            widgets = {
                'my_foreignkey': ForeignKeyLinkedRawIdWidget(),
            }
    
    class MyModelAdmin(admin.ModelAdmin):
        form = MyForm
    

    但是,将其作为“假”readonly_field 添加到实际字段下方会更简单:

    from django.core.urlresolvers import reverse
    from django.utils.html import format_html
    
    class MyModelAdmin(admin.ModelAdmin):
        readonly_fields = ['my_foreignkey_link']
        raw_id_fields = ['my_foreignkey']
        fields = [..., 'my_foreignkey', 'my_foreignkey_link', ...]
    
        def my_foreignkey_link(self, instance):
            if instance:
                fk_id = instance.my_foreignkey_id
            else:
                fk_id = None
            if fk_id:
                opts = instance._meta.get_field('my_foreignkey').rel.model._meta
                related_url = reverse(
                    'admin:{}_{}_change'.format(
                         opts.app_label,
                         opts.model_name,
                    ),
                    args=[fk_id],
                )
                return format_html(
                     '<a target=_blank href="{}">Go!</a>', related_url)
            else:
                return "No related object"
        my_foreignkey_link.short_description = "Edit My FK"
    

    延伸阅读:https://docs.djangoproject.com/en/1.9/ref/contrib/admin/#django.contrib.admin.ModelAdmin.readonly_fields

    【讨论】:

    • 谢谢。我有一个问题。 “实例”是什么意思,为什么要使用“user_id”?这只是一个例子吗?如果我的表的主键只是'id',我应该使用'instance.id'。我不明白“实例”的目的是什么。再次感谢。
    • instance 是您正在编辑的模型的实例。 instance.user_id 等价于 instance.user.id 但如果你这样做 instance.user.id,这将查询数据库以获取用户,这是你想要避免的。
    • 我已经尝试了第二种解决方案。 “编辑我的外键”字段已创建,但除了连字符外什么都没有。
    • 如果你的外键名为flat_house,你应该使用instance.flat_house_id而不是instance.user_id。我不知道为什么我突然将外键命名为user,而我到处都将它命名为my_foreignkey。让我解决这个问题以适合我的示例。
    • opts.ha, opts.house 也是无效的。坚持我给你的代码(只用你的外键的实际名称改变所有出现的my_foreignkey),你以后就可以调整它了。
    【解决方案2】:

    这是一个为我做的 sn-p 页面(更新了 6 年):

    https://djangosnippets.org/snippets/2217/

    只需使用ImproveRawIdFieldsForm 代替ModelAdmin,所有 raw_id 字段都会自动链接显示在 id 输入旁边的对象名称。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-08-11
      • 2011-09-01
      • 2017-05-25
      • 2013-03-21
      • 2020-12-08
      • 2011-02-20
      • 1970-01-01
      相关资源
      最近更新 更多