如何从管理员更改页面隐藏字段,但将其保留在 Django 的管理员添加页面中

时间:2021-01-14 13:14:55

标签: python django django-models django-forms django-admin

我有一个数据模型,其中某些字段只能在每个类的每个实例的初始设置,一旦设置,它们就永远不会改变。允许更改此类对象的唯一方法应该是删除它并创建一个新对象。

伪代码:

from django.db import models
from django.core.exceptions import ValidationError


class NetworkConnection(models.Model):
    description = models.CharField(max_length=1000)
    config = models.CharField(max_length=1000)
    connection_info = models.CharField(max_length=5000)
    def clean(self):
        from .methods import establish_connection
        self.connection_info = establish_connection(self.config)
        if not self.connection_info:
            raise ValidationError('Unable to connect')
    def delete(self):
        from .methods import close_connection
        close_connection(self.config)
        super(NetworkConnection, self).delete()

与上面的代码一样,用户最初应该同时输入 configdescription 字段。然后 Django 验证 config 并根据此类配置建立某种网络连接,并将其信息保存到另一个名为 connection_info 的字段中。

现在由于这个类的每个对象都代表一旦创建就无法编辑的东西,我需要从编辑对象的管理页面隐藏 config 字段,只留下描述字段;但是,添加新连接时 config 字段仍然需要存在。我该怎么做?

以下是我最后一次 admin.py 尝试的示例:

from django.contrib import admin
from .models import NetworkConnection

class NetworkConnectionAdmin(admin.ModelAdmin):
    exclude = ('connection_info')
    def change_view(self, request, object_id, extra_context=None):       
        self.exclude = ('config')
        return super(NetworkConnection, self).change_view(request, object_id, extra_context)

admin.site.register(NetworkConnection, NetworkConnectionAdmin)

但不幸的是,它似乎也隐藏了 add 页面中的 config 字段。不仅是变化页面

2 个答案:

答案 0 :(得分:1)

您可以直接在 NetworkConnectionAdmin 类中使用自定义方法来实现:

from django.contrib import admin
from .models import NetworkConnection

class NetworkConnectionAdmin(admin.ModelAdmin):
    exclude = ('connection_info')

    def get_readonly_fields(self, request, obj=None):
        if obj:
            return ["config", "description"]
        else:
            return []

admin.site.register(NetworkConnection, NetworkConnectionAdmin)

我从 Django Admin Cookbook 那里得到的。

答案 1 :(得分:0)

事实证明这可以使用 ModelAdmin.get_from 函数完成,但如果有人有更好的答案,请分享

使用 get_from 的解决方案是:

admin.py

from django.contrib import admin
from .models import NetworkConnection

class NetworkConnectionAdmin(admin.ModelAdmin):
    exclude = ('connection_info')
    def get_form(self, request, obj=None, **kwargs):
        if obj:
            kwargs['exclude'] = ('config')
        return super(NetworkConnectionAdmin, self).get_form(request, obj, **kwargs)
admin.site.register(NetworkConnection, NetworkConnectionAdmin)