如何从管理更改页面隐藏字段但将其保留在 Django 的管理添加页面中
How to hide field from admin change page but keep it in admin add page in Django
我有一个数据模型,其中某些字段最初只能针对 class 的每个实例设置,并且一旦设置,它们就永远不会改变。允许更改此类对象的唯一方法应该是删除它并创建一个新对象。
伪代码:
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()
如上面的代码一样,用户应该首先输入 config
和 description
字段。然后 Django 验证 config
并根据这些配置建立某种网络连接,并将其信息保存到另一个名为 connection_info
.
的字段中
现在,由于这个 class 的每个对象都代表了一些一旦创建就无法编辑的东西,我需要从编辑对象的管理页面隐藏 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
字段。不仅改变页面
事实证明这可以使用 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)
您可以直接在 NetworkConnectionAdmin 中使用自定义方法实现此目的 class:
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 那里得到的。
我有一个数据模型,其中某些字段最初只能针对 class 的每个实例设置,并且一旦设置,它们就永远不会改变。允许更改此类对象的唯一方法应该是删除它并创建一个新对象。
伪代码:
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()
如上面的代码一样,用户应该首先输入 config
和 description
字段。然后 Django 验证 config
并根据这些配置建立某种网络连接,并将其信息保存到另一个名为 connection_info
.
现在,由于这个 class 的每个对象都代表了一些一旦创建就无法编辑的东西,我需要从编辑对象的管理页面隐藏 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
字段。不仅改变页面
事实证明这可以使用 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)
您可以直接在 NetworkConnectionAdmin 中使用自定义方法实现此目的 class:
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 那里得到的。