व्यवस्थापक में, मैं ऑब्जेक्ट को संशोधित करते समय किसी फ़ील्ड को अक्षम करना चाहूंगा, लेकिन नई ऑब्जेक्ट जोड़ते समय इसे आवश्यक कर दूंगा।
इस बारे में जाने के लिए django तरीका क्या है?
जवाबों:
आप व्यवस्थापक की 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
इस समाधान का परीक्षण Django 1.11 पर किया गया है
FYI करें: यदि कोई अन्य दो समस्याओं का सामना करता है तो मैं उसी में भाग लेता हूं:
आपको अभी भी कक्षा के शरीर में किसी भी स्थायी रूप से readonly_fields घोषित करना चाहिए, क्योंकि readonly_fields वर्ग विशेषता सत्यापन से एक्सेस की जाएगी (देखें django.contrib.admin.validation: validate_fase) (line.213 appx)
यह इनलाइन के साथ काम नहीं करेगा क्योंकि obj को get_readonly_fields () पेरेंट obj पास किया गया है (मेरे पास दो नहीं बल्कि हैसी और सीएसएस या 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
इनलाइन फॉर्म के साथ स्थिति अभी भी Django 2.2.x के लिए तय नहीं है, लेकिन जॉन से समाधान वास्तव में बहुत स्मार्ट है।
कोड मेरी स्थिति से थोड़ा सा जुड़ा:
class NoteListInline(admin.TabularInline):
""" Notes list, readonly """
model = Note
verbose_name = _('Note')
verbose_name_plural = _('Notes')
extra = 0
fields = ('note', 'created_at')
readonly_fields = ('note', 'created_at')
def has_add_permission(self, request, obj=None):
""" Only add notes through AddInline """
return False
class NoteAddInline(admin.StackedInline):
""" Notes edit field """
model = Note
verbose_name = _('Note')
verbose_name_plural = _('Notes')
extra = 1
fields = ('note',)
can_delete = False
def get_queryset(self, request):
queryset = super().get_queryset(request)
return queryset.none() # no existing records will appear
@admin.register(MyModel)
class MyModelAdmin(admin.ModelAdmin):
# ...
inlines = (NoteListInline, NoteAddInline)
# ...
आप ModelAdmin के formfield_for_foreignkey विधि को ओवरराइड करके ऐसा कर सकते हैं:
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)
एक समान समस्या है। मैंने इसे ModelAdmin में "add_fieldsets" और "प्रतिबंधित_fieldsets" के साथ हल किया।
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/
ग्रीज, निक