администратор django создает поле только для чтения при изменении объекта, но требуется при добавлении нового объекта
в admin я хотел бы отключить поле при изменении объекта, но сделать его обязательным при добавлении нового объекта.
что Джанго способ пойти об этом?
6 ответов:
вы можете переопределить администратора
get_readonly_fields
способ:class MyModelAdmin(admin.ModelAdmin): def get_readonly_fields(self, request, obj=None): if obj: # editing an existing object return self.readonly_fields + ('field1', 'field2') return self.readonly_fields
Если вы хотите установить все поля только для чтения просто в представлении изменения переопределите get_readonly_fields администратора:
def get_readonly_fields(self, request, obj=None): if obj: # editing an existing object # All model fields as read_only return self.readonly_fields + tuple([item.name for item in obj._meta.fields]) return self.readonly_fields
и если вы хотите скрыть кнопки сохранения при изменении вида:
изменить вид
def change_view(self, request, object_id, form_url='', extra_context=None): ''' customize edit form ''' extra_context = extra_context or {} extra_context['show_save_and_continue'] = False extra_context['show_save'] = False extra_context['show_save_and_add_another'] = False # this not works if has_add_permision is True return super(TransferAdmin, self).change_view(request, object_id, extra_context=extra_context)
изменить разрешения, если пользователь пытается редактировать:
def has_add_permission(self, request, obj=None): # Not too much elegant but works to hide show_save_and_add_another button if '/change/' in str(request): return False return True
Это решение было протестировано свыше Джанго 1.11
FYI: в случае, если кто - то еще сталкивается с теми же двумя проблемами, с которыми я столкнулся:
вы все равно должны объявить все постоянно readonly_fields в теле класса, так как атрибут класса readonly_fields будет доступен из проверки (см. django.ВНО.администратор.проверка: validate_base (), line.213 appx)
Это не будет работать с Inlines, поскольку obj, переданный get_readonly_fields (), является родительским obj (у меня есть два довольно хаки и решения с низким уровнем безопасности с использованием css или js)
вариант, основанный на предыдущем превосходном предложении Бернхарда Валланта, который также сохраняет любую возможную настройку, предоставляемую базовым классом (если таковые имеются):
class MyModelAdmin(BaseModelAdmin): def get_readonly_fields(self, request, obj=None): readonly_fields = super(MyModelAdmin, self).get_readonly_fields(request, obj) if obj: # editing an existing object return readonly_fields + ['field1', ..] return readonly_fields
вы можете сделать это, переопределив метод formfield_for_foreignkey ModelAdmin:
from django import forms from django.contrib import admin from yourproject.yourapp.models import YourModel class YourModelAdmin(admin.ModelAdmin): class Meta: model = YourModel def formfield_for_foreignkey(self, db_field, request=None, **kwargs): # Name of your field here if db_field.name == 'add_only': if request: add_opts = (self._meta.app_label, self._meta.module_name) add = u'/admin/%s/%s/add/' % add_opts if request.META['PATH_INFO'] == add: field = db_field.formfield(**kwargs) else: kwargs['widget'] = forms.HiddenInput() field = db_field.formfield(**kwargs) return field return admin.ModelAdmin(self, db_field, request, **kwargs)
получил аналогичную проблему. Я решил его с помощью "add_fieldsets" и "restricted_fieldsets" в ModelAdmin.
from django.contrib import admin class MyAdmin(admin.ModelAdmin): declared_fieldsets = None restricted_fieldsets = ( (None, {'fields': ('mod_obj1', 'mod_obj2')}), ( 'Text', {'fields': ('mod_obj3', 'mod_obj4',)}), ) add_fieldsets = ( (None, { 'classes': ('wide',), 'fields': ('add_obj1', 'add_obj2', )}), )
смотрите, например:http://code.djangoproject.com/svn/django/trunk/django/contrib/auth/admin.py
но это не защищает вашу модель от последующих изменений "add_objX". Если вы тоже этого хотите, я думаю, вам нужно пройти через функцию "Сохранить" класса модели и проверить наличие изменений там.
посмотреть: www.djangoproject.com/documentation/models/save_delete_hooks/
Greez, Ник