use*_*888 21 django django-admin
我在Django管理员中有一个表格内联模型.我需要1个字段在创建后不可更改,但将其设置为readonly(通过readonly_fields),工作正常,但在单击"添加其他项目"而不是下拉列表时将字段转换为标签.
有没有办法保持字段只读,但仍允许使用正确的字段输入创建新项目?
谢谢!
托马斯
编辑:管理通过自定义小部件来计算出来
class ReadOnlySelectWidget(forms.Select):
def render(self, name, value, attrs=None):
if value:
final_attrs = self.build_attrs(attrs, name=name)
output = u'<input value="%s" type="hidden" %s />' % (value, flatatt(final_attrs))
return mark_safe(output + str(self.choices.queryset.get(id=value)))
else:
return super(ReadOnlySelectWidget, self).render(name, value, attrs)
Run Code Online (Sandbox Code Playgroud)
如果有值,它只会将其变为隐藏,在每种情况下都不会起作用(仅适用于1个只读字段).
ole*_*sse 40
遇到同样的问题,我遇到了这个问题:
创建两个内联对象,一个没有更改权限,另一个包含所有字段只读.包括在模型管理员中.
class SubscriptionInline(admin.TabularInline):
model = Subscription
extra = 0
readonly_fields = ['subscription', 'usedPtsStr', 'isActive', 'activationDate', 'purchaseDate']
def has_add_permission(self, request):
return False
class AddSupscriptionInline(admin.TabularInline):
model = Subscription
extra = 0
fields = ['subscription', 'usedPoints', 'isActive', 'activationDate', 'purchaseDate']
def has_change_permission(self, request, obj=None):
return False
# For Django Version > 2.1 there is a "view permission" that needs to be disabled too (https://docs.djangoproject.com/en/2.2/releases/2.1/#what-s-new-in-django-2-1)
def has_view_permission(self, request, obj=None):
return False
Run Code Online (Sandbox Code Playgroud)
将它们包含在同一模型管理员中:
class UserAdmin(admin.ModelAdmin):
inlines = [ AddSupscriptionInline, SubscriptionInline]
Run Code Online (Sandbox Code Playgroud)
要添加新订阅,我AddSubscriptionInline在管理员中使用.保存后,新订阅将从内联中消失,但现在确实SubscriptionInline以只读方式显示在内联中.
因为SubscriptionInline,重要的是要提及extra = 0,因此它不会显示垃圾只读订阅.最好隐藏添加选项SubscriptionInline,以允许仅添加通过AddSubscriptionInline设置has_add_permission始终返回False.
根本不完美,但它对我来说是最好的选择,因为我必须提供在用户管理页面上添加订阅的功能,但是在添加一个之后,它应该仅通过内部应用程序逻辑进行更改.
你可以只用一个内联来实现这一点,如下所示:
class MyInline(admin.TabularInline):
fields = [...]
extra = 0
def has_change_permission(self, request, obj):
return False
Run Code Online (Sandbox Code Playgroud)
这可以通过猴子补丁来实现。
以下示例将使现有 AdminNote 对象的“note”字段变为只读。与其他答案中建议的将字段转换为隐藏不同,这实际上将从提交/验证工作流程中删除字段(这更安全并使用现有的字段渲染器)。
#
# app/models.py
#
class Order(models.Model):
pass
class AdminNote(models.Model):
order = models.ForeignKey(Order)
time = models.DateTimeField(auto_now_add=True)
note = models.TextField()
#
# app/admin.py
#
import monkey_patches.admin_fieldset
...
class AdminNoteForm(forms.ModelForm):
class Meta:
model = AdminNote
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
for field in self.get_readonly_fields():
del self.fields[field]
def get_readonly_fields(self):
if self.instance.pk:
return ['note']
return []
class AdminNoteInline(admin.TabularInline):
model = AdminNote
form = AdminNoteForm
extra = 1
fields = 'note', 'time'
readonly_fields = 'time',
@admin.register(Order)
class OrderAdmin(admin.ModelAdmin):
inlines = AdminNoteInline,
#
# monkey_patches/admin_fieldset.py
#
import django.contrib.admin.helpers
class Fieldline(django.contrib.admin.helpers.Fieldline):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
if hasattr(self.form, 'get_readonly_fields'):
self.readonly_fields = list(self.readonly_fields) + list(self.form.get_readonly_fields())
django.contrib.admin.helpers.Fieldline = Fieldline
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
11667 次 |
| 最近记录: |