def get_model_form(self, **kwargs): """ Returns a Form class for use in the admin add view. This is used by add_view and change_view. """ if self.exclude is None: exclude = [] else: exclude = list(self.exclude) if self.exclude is None and hasattr( self.form, '_meta') and self.form._meta.exclude: # Take the custom ModelForm's Meta.exclude into account only if the # ModelAdmin doesn't define its own. exclude.extend(self.form._meta.exclude) # if exclude is an empty list we pass None to be consistant with the # default on modelform_factory exclude = exclude or None defaults = { "form": self.form, "fields": self.fields and list(self.fields) or None, "exclude": exclude, } defaults.update(kwargs) if defaults['fields'] is None and not modelform_defines_fields( defaults['form']): defaults['fields'] = forms.ALL_FIELDS return modelform_factory(self.model, **defaults)
def get_model_form(self, **kwargs): """ Returns a Form class for use in the admin add view. This is used by add_view and change_view. """ if self.exclude is None: exclude = [] else: exclude = list(self.exclude) exclude.extend(self.get_readonly_fields()) if self.exclude is None and hasattr(self.form, '_meta') and self.form._meta.exclude: # Take the custom ModelForm's Meta.exclude into account only if the # ModelAdmin doesn't define its own. exclude.extend(self.form._meta.exclude) # if exclude is an empty list we pass None to be consistant with the # default on modelform_factory exclude = exclude or None defaults = { "form": self.form, "fields": self.fields and list(self.fields) or None, "exclude": exclude, "formfield_callback": self.formfield_for_dbfield, } defaults.update(kwargs) if defaults['fields'] is None and not modelform_defines_fields(defaults['form']): defaults['fields'] = forms.ALL_FIELDS # return modelform_factory(self.model, **defaults) try: return modelform_factory(self.model, **defaults) except FieldError as e: raise FieldError('%s. Check fields/fieldsets/exclude attributes of class %s.' % (e, self.__class__.__name__))
def get_model_form(self, **kwargs): """ Returns a Form class for use in the admin add view. This is used by add_view and change_view. """ if self.exclude is None: exclude = [] else: exclude = list(self.exclude) exclude.extend(self.get_readonly_fields()) if self.exclude is None and hasattr(self.form, '_meta') and self.form._meta.exclude: # Take the custom ModelForm's Meta.exclude into account only if the # ModelAdmin doesn't define its own. exclude.extend(self.form._meta.exclude) # if exclude is an empty list we pass None to be consistant with the # default on modelform_factory exclude = exclude or None defaults = { "form": self.form, "fields": self.fields and list(self.fields) or None, "exclude": exclude, "formfield_callback": self.formfield_for_dbfield, } defaults.update(kwargs) if defaults['fields'] is None and not modelform_defines_fields(defaults['form']): defaults['fields'] = forms.ALL_FIELDS return modelform_factory(self.model, **defaults) try: return modelform_factory(self.model, **defaults) except FieldError as e: raise FieldError('%s. Check fields/fieldsets/exclude attributes of class %s.' % (e, self.__class__.__name__))
def get_formset(self, request, obj=None, **kwargs): if 'fields' in kwargs: fields = kwargs.pop('fields') else: fields = flatten_fieldsets(self.get_fieldsets(request, obj)) if self.exclude is None: exclude = [] else: exclude = list(self.exclude) exclude.extend(self.get_readonly_fields(request, obj)) if self.exclude is None and hasattr(self.form, '_meta') and self.form._meta.exclude: # Take the custom ModelForm's Meta.exclude into account only if the # GenericInlineModelAdmin doesn't define its own. exclude.extend(self.form._meta.exclude) exclude = exclude or None can_delete = self.can_delete and self.has_delete_permission(request, obj) defaults = { "ct_field": self.ct_field, "fk_field": self.ct_fk_field, "form": self.form, "formfield_callback": partial(self.formfield_for_dbfield, request=request), "formset": self.formset, "extra": self.extra, "can_delete": can_delete, "can_order": False, "fields": fields, "max_num": self.max_num, "exclude": exclude } defaults.update(kwargs) if defaults['fields'] is None and not modelform_defines_fields(defaults['form']): defaults['fields'] = ALL_FIELDS return generic_inlineformset_factory(self.model, **defaults)
def get_formset(self, request, obj=None, **kwargs): if 'fields' in kwargs: fields = kwargs.pop('fields') else: fields = flatten_fieldsets(self.get_fieldsets(request, obj)) exclude = [*(self.exclude or []), *self.get_readonly_fields(request, obj)] if self.exclude is None and hasattr(self.form, '_meta') and self.form._meta.exclude: # Take the custom ModelForm's Meta.exclude into account only if the # GenericInlineModelAdmin doesn't define its own. exclude.extend(self.form._meta.exclude) exclude = exclude or None can_delete = self.can_delete and self.has_delete_permission(request, obj) defaults = { 'ct_field': self.ct_field, 'fk_field': self.ct_fk_field, 'form': self.form, 'formfield_callback': partial(self.formfield_for_dbfield, request=request), 'formset': self.formset, 'extra': self.get_extra(request, obj), 'can_delete': can_delete, 'can_order': False, 'fields': fields, 'min_num': self.get_min_num(request, obj), 'max_num': self.get_max_num(request, obj), 'exclude': exclude, **kwargs, } if defaults['fields'] is None and not modelform_defines_fields(defaults['form']): defaults['fields'] = ALL_FIELDS return generic_inlineformset_factory(self.model, **defaults)
def get_formset(self, request, obj=None, **kwargs): if 'fields' in kwargs: fields = kwargs.pop('fields') else: fields = flatten_fieldsets(self.get_fieldsets(request, obj)) exclude = [*(self.exclude or []), *self.get_readonly_fields(request, obj)] if self.exclude is None and hasattr(self.form, '_meta') and self.form._meta.exclude: # Take the custom ModelForm's Meta.exclude into account only if the # GenericInlineModelAdmin doesn't define its own. exclude.extend(self.form._meta.exclude) exclude = exclude or None can_delete = self.can_delete and self.has_delete_permission(request, obj) defaults = { 'ct_field': self.ct_field, 'fk_field': self.ct_fk_field, 'form': self.form, 'formfield_callback': partial(self.formfield_for_dbfield, request=request), 'formset': self.formset, 'extra': self.get_extra(request, obj), 'can_delete': can_delete, 'can_order': False, 'fields': fields, 'min_num': self.get_min_num(request, obj), 'max_num': self.get_max_num(request, obj), 'exclude': exclude, **kwargs, } if defaults['fields'] is None and not modelform_defines_fields(defaults['form']): defaults['fields'] = ALL_FIELDS return generic_inlineformset_factory(self.model, **defaults)
def get_formset(self, request, obj=None, **kwargs): if self.declared_fieldsets: fields = flatten_fieldsets(self.declared_fieldsets) else: fields = None if self.exclude is None: exclude = [] else: exclude = list(self.exclude) exclude.extend(self.get_readonly_fields(request, obj)) if self.exclude is None and hasattr(self.form, "_meta") and self.form._meta.exclude: # Take the custom ModelForm's Meta.exclude into account only if the # GenericInlineModelAdmin doesn't define its own. exclude.extend(self.form._meta.exclude) exclude = exclude or None can_delete = self.can_delete and self.has_delete_permission(request, obj) defaults = { "ct_field": self.ct_field, "fk_field": self.ct_fk_field, "form": self.form, "formfield_callback": partial(self.formfield_for_dbfield, request=request), "formset": self.formset, "extra": self.extra, "can_delete": can_delete, "can_order": False, "fields": fields, "max_num": self.max_num, "exclude": exclude, } defaults.update(kwargs) if defaults["fields"] is None and not modelform_defines_fields(defaults["form"]): defaults["fields"] = ALL_FIELDS return generic_inlineformset_factory(self.model, **defaults)
def _get_form_factory_opts(self, request, obj=None, **kwargs): fieldsets = self.get_fieldsets(request, obj) if fieldsets: fields = flatten_fieldsets(fieldsets) else: fields = None if self.exclude is None: exclude = [] else: exclude = list(self.exclude) exclude.extend(self.get_readonly_fields(request, obj)) if self.exclude is None and hasattr(self.form, '_meta') and self.form._meta.exclude: # Take the custom ModelForm's Meta.exclude into account only if the # ModelAdmin doesn't define its own. exclude.extend(self.form._meta.exclude) # construct the form_opts from declared_fieldsets form_opts = self.app_form_opts.copy() if fields is not None: # put app_name prefixed fields into form_opts for f in fields: if '.' not in f: continue label, name = f.split('.') app_fields = form_opts.setdefault(label, {}).setdefault('fields', []) if name not in app_fields: app_fields.append(name) # .. and remove them from fields for the model form fields = [f for f in fields if '.' not in f] # do the same for exclude for f in exclude: if '.' not in f: continue label, name = f.split('.') app_fields = form_opts.setdefault(label, {}).setdefault('exclude', []) if name not in app_fields: app_fields.append(name) exclude = [f for f in exclude if '.' not in f] # if exclude is an empty list we pass None to be consistant with the # default on modelform_factory exclude = exclude or None defaults = { "form": self.form, "multiform": self.multiform, "form_opts": form_opts, "fields": fields, "exclude": exclude, "formfield_callback": partial(self.formfield_for_dbfield, request=request), } defaults.update(kwargs) if hasattr(forms, 'ALL_FIELDS'): # Django 1.7 if defaults['fields'] is None and not modelform_defines_fields(defaults['form']): defaults['fields'] = forms.ALL_FIELDS return defaults
def get_form(self, request, obj=None, **kwargs): if 'fields' in kwargs: fields = kwargs.pop('fields') else: fields = flatten_fieldsets(self.get_fieldsets(request, obj)) excluded = self.get_exclude(request, obj) exclude = [] if excluded is None else list(excluded) readonly_fields = self.get_readonly_fields(request, obj) exclude.extend(readonly_fields) if excluded is None and hasattr(self.form, '_meta') and self.form._meta.exclude: # Take the custom ModelForm's Meta.exclude into account only if the # ModelAdmin doesn't define its own. exclude.extend(self.form._meta.exclude) # if exclude is an empty list we pass None to be consistent with the # default on modelform_factory exclude = exclude or None new_attrs = OrderedDict( (f, None) for f in readonly_fields if f in self.form.declared_fields ) form = type(self.form.__name__, (self.form,), new_attrs) try: model = obj.content_type.model_class() model_key = model._meta.pk.name except (AttributeError, ObjectDoesNotExist): model = self.model.content_type.field.formfield().choices.queryset[0].model_class() model_key = 'id' defaults = { "form": form, "fields": fields, "exclude": exclude, "formfield_callback": partial(self.formfield_for_dbfield, request=request), "widgets": { 'content_type': ContentTypeSelect, 'object_id': ForeignKeyRawIdWidget( rel=ManyToOneRel(model_key, model, 'id'), admin_site=admin.site ) } } defaults.update(kwargs) if defaults['fields'] is None and not modelform_defines_fields(defaults['form']): defaults['fields'] = forms.ALL_FIELDS try: return modelform_factory(self.model, **defaults) except FieldError as e: raise FieldError( '%s. Check fields/fieldsets/exclude attributes of class %s.' % (e, self.__class__.__name__) )
def get_formset(self, request, obj=None, **kwargs): if 'fields' in kwargs: fields = kwargs.pop('fields') else: fields = flatten_fieldsets(self.get_fieldsets(request, obj)) exclude = [ *(self.exclude or []), *self.get_readonly_fields(request, obj) ] if self.exclude is None and hasattr( self.form, '_meta') and self.form._meta.exclude: exclude.extend(self.form._meta.exclude) exclude = exclude or None can_delete = self.can_delete and self.has_delete_permission( request, obj) queryset = self.model.objects.none() if obj: queryset = self.get_form_queryset(obj) defaults = { 'form': self.form, 'formfield_callback': partial(self.formfield_for_dbfield, request=request), 'formset': self.formset, 'extra': self.get_extra(request, obj), 'can_delete': can_delete, 'can_order': False, 'fields': fields, 'min_num': self.get_min_num(request, obj), 'max_num': self.get_max_num(request, obj), 'exclude': exclude, 'queryset': queryset, **kwargs, } if defaults['fields'] is None and not modelform_defines_fields( defaults['form']): defaults['fields'] = ALL_FIELDS return nonrelated_inlineformset_factory( self.model, save_new_instance=self.save_new_instance, **defaults)
def get_changelist_form(self, request, **kwargs): """ Returns a Form class for use in the Formset on the changelist page. """ defaults = { "formfield_callback": partial(self.formfield_for_dbfield, request=request), } defaults.update(kwargs) if defaults.get('fields') is None and not modelform_defines_fields(defaults.get('form')): defaults['fields'] = forms.ALL_FIELDS return documentform_factory(self.model, **defaults)
def get_changelist_form(self, request, **kwargs): """ Returns a Form class for use in the Formset on the changelist page. """ defaults = { "formfield_callback": partial(self.formfield_for_dbfield, request=request), } defaults.update(kwargs) if defaults.get('fields') is None and not modelform_defines_fields(defaults.get('form')): defaults['fields'] = forms.ALL_FIELDS return documentform_factory(self.model, **defaults)
def get_formset(self, request, obj=None, **kwargs): if "fields" in kwargs: fields = kwargs.pop("fields") else: fields = flatten_fieldsets(self.get_fieldsets(request, obj)) exclude = [ *(self.exclude or []), *self.get_readonly_fields(request, obj) ] if (self.exclude is None and hasattr(self.form, "_meta") and self.form._meta.exclude): # Take the custom ModelForm's Meta.exclude into account only if the # GenericInlineModelAdmin doesn't define its own. exclude.extend(self.form._meta.exclude) exclude = exclude or None can_delete = self.can_delete and self.has_delete_permission( request, obj) defaults = { "ct_field": self.ct_field, "fk_field": self.ct_fk_field, "form": self.form, "formfield_callback": partial(self.formfield_for_dbfield, request=request), "formset": self.formset, "extra": self.get_extra(request, obj), "can_delete": can_delete, "can_order": False, "fields": fields, "min_num": self.get_min_num(request, obj), "max_num": self.get_max_num(request, obj), "exclude": exclude, **kwargs, } if defaults["fields"] is None and not modelform_defines_fields( defaults["form"]): defaults["fields"] = ALL_FIELDS return generic_inlineformset_factory(self.model, **defaults)
def get_form(self, request, obj=None, **kwargs): if MODELADMIN_GET_EXCLUDE_SUPPORT: return super().get_form(request, obj, **kwargs) if 'fields' in kwargs: fields = kwargs.pop('fields') else: fields = flatten_fieldsets(self.get_fieldsets(request, obj)) excluded = self.get_exclude(request, obj) exclude = [] if excluded is None else list(excluded) readonly_fields = self.get_readonly_fields(request, obj) exclude.extend(readonly_fields) if excluded is None and hasattr(self.form, '_meta') and self.form._meta.exclude: exclude.extend(self.form._meta.exclude) exclude = exclude or None new_attrs = OrderedDict((f, None) for f in readonly_fields if f in self.form.declared_fields) form = type(self.form.__name__, (self.form, ), new_attrs) defaults = { "form": form, "fields": fields, "exclude": exclude, "formfield_callback": partial(self.formfield_for_dbfield, request=request), } defaults.update(kwargs) if defaults['fields'] is None and not modelform_defines_fields( defaults['form']): defaults['fields'] = ALL_FIELDS try: return modelform_factory(self.model, **defaults) except FieldError as e: raise FieldError( '%s. Check fields/fieldsets/exclude attributes of class %s.' % (e, self.__class__.__name__))
def get_form(self, request, obj=None, **kwargs): """ Returns a Form class for use in the admin add view. This is used by add_view and change_view. """ if 'fields' in kwargs: fields = kwargs.pop('fields') else: fields = flatten_fieldsets(self.get_fieldsets(request, obj)) if self.exclude is None: exclude = [] else: exclude = list(self.exclude) exclude.extend(self.get_readonly_fields(request, obj)) if self.exclude is None and hasattr( self.form, '_meta') and self.form._meta.exclude: # Take the custom ModelForm's Meta.exclude into account only if the # ModelAdmin doesn't define its own. exclude.extend(self.form._meta.exclude) # if exclude is an empty list we pass None to be consistent with the # default on modelform_factory exclude = exclude or None defaults = { "form": self.form, "fields": fields, "exclude": exclude, "formfield_callback": partial(self.formfield_for_dbfield, request=request), } defaults.update(kwargs) if defaults['fields'] is None and not modelform_defines_fields( defaults['form']): defaults['fields'] = None print(defaults) try: return documentform_factory(self.model, **defaults) except FieldError as e: print(e.message) raise FieldError( '%s. Check fields/fieldsets/exclude attributes of class %s.' % (e, self.__class__.__name__))
def get_changelist_form(self, request, **kwargs): """ Return a Form class for use in the Formset on the changelist page. """ # BEGIN CUSTOMIZATION defaults = { "formfield_callback": partial( # Override formfield_callback so checkboxes render correctly self.changelist_formfield_for_dbfield, request=request, ), **kwargs, } # END CUSTOMIZATION if defaults.get("fields") is None and not modelform_defines_fields( defaults.get("form")): defaults["fields"] = forms.ALL_FIELDS return modelform_factory(self.model, **defaults)
def get_formset(self, request, obj=None, **kwargs): if 'fields' in kwargs: fields = kwargs.pop('fields') else: fields = flatten_fieldsets(self.get_fieldsets(request, obj)) if self.exclude is None: exclude = [] else: exclude = list(self.exclude) exclude.extend(self.get_readonly_fields(request, obj)) if (self.exclude is None and hasattr(self.form, '_meta') and self.form._meta.exclude): # Take the custom ModelForm's Meta.exclude into account only if the # GenericInlineModelAdmin doesn't define its own. exclude.extend(self.form._meta.exclude) exclude = exclude or None can_delete = (self.can_delete and self.has_delete_permission(request, obj)) defaults = { "model_field": self.model_field, "parent_model_field": self.parent_model_field, "form": self.form, "formfield_callback": partial(self.formfield_for_dbfield, request=request), "formset": self.formset, "extra": self.get_extra(request, obj), "can_delete": can_delete, "can_order": False, "fields": fields, "min_num": self.get_min_num(request, obj), "max_num": self.get_max_num(request, obj), "exclude": exclude } defaults.update(kwargs) if (defaults['fields'] is None and not modelform_defines_fields(defaults['form'])): defaults['fields'] = ALL_FIELDS return arbitrary_inlineformset_factory(self.model, self.parent_model, **defaults)
def get_form(self, request, obj=None, **kwargs): """ Returns a Form class for use in the admin add view. This is used by add_view and change_view. """ if 'fields' in kwargs: fields = kwargs.pop('fields') else: fields = flatten_fieldsets(self.get_fieldsets(request, obj)) if self.exclude is None: exclude = [] else: exclude = list(self.exclude) exclude.extend(self.get_readonly_fields(request, obj)) if self.exclude is None and hasattr(self.form, '_meta') and self.form._meta.exclude: # Take the custom ModelForm's Meta.exclude into account only if the # ModelAdmin doesn't define its own. exclude.extend(self.form._meta.exclude) # if exclude is an empty list we pass None to be consistent with the # default on modelform_factory exclude = exclude or None defaults = { "form": self.form, "fields": fields, "exclude": exclude, "formfield_callback": partial(self.formfield_for_dbfield, request=request), } defaults.update(kwargs) if defaults['fields'] is None and not modelform_defines_fields(defaults['form']): defaults['fields'] = None print(defaults) try: return documentform_factory(self.model, **defaults) except FieldError as e: print(e.message) raise FieldError('%s. Check fields/fieldsets/exclude attributes of class %s.' % (e, self.__class__.__name__))
def get_model_form(self, **kwargs): """ 根据 Model 返回 Form 类,用来显示表单。 """ if self.exclude is None: exclude = [] else: exclude = list(self.exclude) exclude.extend(self.get_readonly_fields()) if self.exclude is None and hasattr( self.form, '_meta') and self.form._meta.exclude: # 如果 :attr:`~xadmin.views.base.ModelAdminView.exclude` 是 None,并且 form 的 Meta.exclude 不为空, # 则使用 form 的 Meta.exclude exclude.extend(self.form._meta.exclude) # 如果 exclude 是空列表,那么就设为 None exclude = exclude or None defaults = { "form": self.form, "fields": self.fields and list(self.fields) or None, "exclude": exclude, "formfield_callback": self.formfield_for_dbfield, # 设置生成表单字段的回调函数 } defaults.update(kwargs) if defaults['fields'] is None and not modelform_defines_fields( defaults['form']): defaults['fields'] = forms.ALL_FIELDS return modelform_factory(self.model, **defaults) try: # 使用 modelform_factory 生成 Form 类 return modelform_factory(self.model, **defaults) except FieldError as e: raise FieldError( '%s. Check fields/fieldsets/exclude attributes of class %s.' % (e, self.__class__.__name__))
def get_formset(self, request, obj=None, **kwargs): if 'fields' in kwargs: fields = kwargs.pop('fields') else: fields = flatten_fieldsets(self.get_fieldsets(request, obj)) if self.exclude is None: exclude = [] else: exclude = list(self.exclude) exclude.extend(self.get_readonly_fields(request, obj)) if self.exclude is None and hasattr( self.form, '_meta') and self.form._meta.exclude: # Take the custom ModelForm's Meta.exclude into account only if the # InlineModelAdmin doesn't define its own. exclude.extend(self.form._meta.exclude) # If exclude is an empty list we use None, since that's the actual # default. exclude = exclude or None can_delete = self.can_delete and self.has_delete_permission( request, obj) defaults = { "form": self.form, "formset": self.formset, "fields": fields, "exclude": exclude, "formfield_callback": partial(self.formfield_for_dbfield, request=request), "extra": self.get_extra(request, obj, **kwargs), "min_num": self.get_min_num(request, obj, **kwargs), "max_num": self.get_max_num(request, obj, **kwargs), "can_delete": can_delete, } defaults.update(kwargs) base_model_form = defaults['form'] class DeleteProtectedModelForm(base_model_form): def hand_clean_DELETE(self): """ We don't validate the 'DELETE' field itself because on templates it's not rendered using the field information, but just using a generic "deletion_field" of the InlineModelAdmin. """ if self.cleaned_data.get(DELETION_FIELD_NAME, False): using = router.db_for_write(self._meta.model) collector = NestedObjects(using=using) if self.instance.pk is None: return collector.collect([self.instance]) if collector.protected: objs = [] for p in collector.protected: objs.append( # Translators: Model verbose name and instance representation, # suitable to be an item in a list. _('%(class_name)s %(instance)s') % { 'class_name': p._meta.verbose_name, 'instance': p }) params = { 'class_name': self._meta.model._meta.verbose_name, 'instance': self.instance, 'related_objects': get_text_list(objs, _('and')) } msg = _( "Deleting %(class_name)s %(instance)s would require " "deleting the following protected related objects: " "%(related_objects)s") raise ValidationError(msg, code='deleting_protected', params=params) def is_valid(self): result = super(DeleteProtectedModelForm, self).is_valid() self.hand_clean_DELETE() return result defaults['form'] = DeleteProtectedModelForm if defaults['fields'] is None and not modelform_defines_fields( defaults['form']): defaults['fields'] = forms.ALL_FIELDS return modelformset_factory(self.model, **defaults)
def get_formset(self, request, obj=None, **kwargs): # noqa: C901 """ Copied from the Django InlineModelAdmin but instead of the inlineformset_factory we use the non_related_inlineformset_factory. """ if 'fields' in kwargs: fields = kwargs.pop('fields') else: fields = flatten_fieldsets(self.get_fieldsets(request, obj)) exclude = [*(self.exclude or []), *self.get_readonly_fields(request, obj)] if self.exclude is None and hasattr(self.form, '_meta') and self.form._meta.exclude: exclude.extend(self.form._meta.exclude) exclude = exclude or None can_delete = self.can_delete and self.has_delete_permission(request, obj) queryset = self.model.objects.none() if obj: queryset = self.get_form_queryset(obj) defaults = { 'form': self.form, 'formfield_callback': partial(self.formfield_for_dbfield, request=request), 'formset': self.formset, 'extra': self.get_extra(request, obj), 'can_delete': can_delete, 'can_order': False, 'fields': fields, 'min_num': self.get_min_num(request, obj), 'max_num': self.get_max_num(request, obj), 'exclude': exclude, 'queryset': queryset, **kwargs, } base_model_form = defaults['form'] can_change = self.has_change_permission(request, obj) if request else True can_add = self.has_add_permission(request, obj) if request else True class DeleteProtectedModelForm(base_model_form): def hand_clean_DELETE(self): """ We don't validate the 'DELETE' field itself because on templates it's not rendered using the field information, but just using a generic "deletion_field" of the InlineModelAdmin. """ if self.cleaned_data.get(DELETION_FIELD_NAME, False): using = router.db_for_write(self._meta.model) collector = NestedObjects(using=using) if self.instance._state.adding: return collector.collect([self.instance]) if collector.protected: objs = [] for p in collector.protected: objs.append( # Translators: Model verbose name and instance representation, # suitable to be an item in a list. _('%(class_name)s %(instance)s') % { 'class_name': p._meta.verbose_name, 'instance': p} ) params = { 'class_name': self._meta.model._meta.verbose_name, 'instance': self.instance, 'related_objects': get_text_list(objs, _('and')), } msg = _("Deleting %(class_name)s %(instance)s would require " "deleting the following protected related objects: " "%(related_objects)s") raise ValidationError(msg, code='deleting_protected', params=params) def is_valid(self): result = super().is_valid() self.hand_clean_DELETE() return result def has_changed(self): # Protect against unauthorized edits. if not can_change and not self.instance._state.adding: return False if not can_add and self.instance._state.adding: return False return super().has_changed() defaults['form'] = DeleteProtectedModelForm if defaults['fields'] is None and not modelform_defines_fields(defaults['form']): defaults['fields'] = ALL_FIELDS return non_related_inlineformset_factory(self.model, save_new_instance=self.save_new_instance, **defaults)
def get_formset(self, request, obj=None, **kwargs): """Return a BaseInlineFormSet class for use in admin add/change views.""" if 'fields' in kwargs: fields = kwargs.pop('fields') else: fields = flatten_fieldsets(self.get_fieldsets(request, obj)) excluded = self.get_exclude(request, obj) exclude = [] if excluded is None else list(excluded) exclude.extend(self.get_readonly_fields(request, obj)) if excluded is None and hasattr(self.form, '_meta') and self.form._meta.exclude: # Take the custom ModelForm's Meta.exclude into account only if the # InlineModelAdmin doesn't define its own. exclude.extend(self.form._meta.exclude) # If exclude is an empty list we use None, since that's the actual # default. exclude = exclude or None can_delete = self.can_delete and self.has_delete_permission( request, obj) defaults = { 'form': self.form, 'formset': self.formset, 'fk_name': self.fk_name, 'fields': fields, 'exclude': exclude, 'formfield_callback': partial(self.formfield_for_dbfield, request=request), 'extra': self.get_extra(request, obj, **kwargs), 'min_num': self.get_min_num(request, obj, **kwargs), 'max_num': self.get_max_num(request, obj, **kwargs), 'can_delete': can_delete, **kwargs, } base_model_form = defaults['form'] can_change = self.has_change_permission(request, obj) if request else True can_add = self._has_add_permission(request, obj) if request else True class SelectProtectedModelForm(base_model_form): def hand_clean_Select(self): """ We don't validate the 'DELETE' field itself because on templates it's not rendered using the field information, but just using a generic "deletion_field" of the InlineModelAdmin. """ if self.cleaned_data.get('pk', None): if not self.cleaned_data.get(DELETION_FIELD_NAME, False): using = router.db_for_write(self._meta.model) collector = NestedObjects(using=using) if self.instance._state.adding: return collector.collect([self.instance]) if collector.protected: objs = [] for p in collector.protected: objs.append( # Translators: Model verbose name and instance representation, # suitable to be an item in a list. _('%(class_name)s %(instance)s') % { 'class_name': p._meta.verbose_name, 'instance': p }) params = { 'class_name': self._meta.model._meta.verbose_name, 'instance': self.instance, 'related_objects': get_text_list(objs, _('and')), } msg = _( "Deleting %(class_name)s %(instance)s would require " "deleting the following protected related objects: " "%(related_objects)s") raise ValidationError(msg, code='deleting_protected', params=params) else: if self.cleaned_data.get(DELETION_FIELD_NAME, False): using = router.db_for_write(self._meta.model) collector = NestedObjects(using=using) if self.instance._state.adding: return def is_valid(self): result = super().is_valid() self.hand_clean_Select() return result def has_changed(self): # Protect against unauthorized edits. if not can_change and not self.instance._state.adding: return False if not can_add and self.instance._state.adding: return False return super().has_changed() defaults['form'] = SelectProtectedModelForm if defaults['fields'] is None and not modelform_defines_fields( defaults['form']): defaults['fields'] = forms.ALL_FIELDS Formset = inlineformset_factory(self.parent_model, self.model, **defaults) Formset.unique_name = self.unique_name Formset.unique_queryset = self.get_unique_queryset() return Formset
def get_form(self, request, obj=None, change=False, **kwargs): """ Return a Form class for use in the admin add view. This is used by add_view and change_view. """ if 'fields' in kwargs: fields = kwargs.pop('fields') else: fields = flatten_fieldsets(self.get_fieldsets(request, obj)) excluded = self.get_exclude(request, obj) exclude = [] if excluded is None else list(excluded) readonly_fields = self.get_readonly_fields(request, obj) exclude.extend(readonly_fields) # Exclude all fields if it's a change form and the user doesn't have # the change permission. if change and hasattr( request, 'user') and not self.has_change_permission(request, obj): exclude.extend(fields) if excluded is None and hasattr(self.form, '_meta') and self.form._meta.exclude: # Take the custom ModelForm's Meta.exclude into account only if the # ModelAdmin doesn't define its own. exclude.extend(self.form._meta.exclude) # if exclude is an empty list we pass None to be consistent with the # default on modelform_factory exclude = exclude or None # Remove declared form fields which are in readonly_fields. new_attrs = OrderedDict.fromkeys(f for f in readonly_fields if f in self.form.declared_fields) # MediaDefiningClass if obj: detail_attrs = dict() for attr in Attribute.objects.filter( related_types__contains=[obj.type]): widget = forms.Textarea if attr.code == "description" else attr.form_field_class.widget detail_attrs['_detail__%s' % attr.code] = attr.form_field_class(label=attr.code, required=False, widget=widget(attrs={ 'class': 'vTextField'}), help_text=attr.name, validators=[ RegexValidator( attr.regex)] if attr.regex \ else []) new_attrs.update(detail_attrs) form = type(self.form.__name__, (self.form, ), new_attrs) defaults = { 'form': form, 'fields': fields, 'exclude': exclude, 'formfield_callback': partial(self.formfield_for_dbfield, request=request), **kwargs, } if defaults['fields'] is None and not modelform_defines_fields( defaults['form']): defaults['fields'] = forms.ALL_FIELDS try: return modelform_factory(self.model, **defaults) except FieldError as e: raise FieldError( '%s. Check fields/fieldsets/exclude attributes of class %s.' % (e, self.__class__.__name__))
def get_formset(self, request, obj=None, **kwargs): if 'fields' in kwargs: fields = kwargs.pop('fields') else: fields = flatten_fieldsets(self.get_fieldsets(request, obj)) if self.exclude is None: exclude = [] else: exclude = list(self.exclude) exclude.extend(self.get_readonly_fields(request, obj)) if self.exclude is None and hasattr(self.form, '_meta') and self.form._meta.exclude: # Take the custom ModelForm's Meta.exclude into account only if the # InlineModelAdmin doesn't define its own. exclude.extend(self.form._meta.exclude) # If exclude is an empty list we use None, since that's the actual # default. exclude = exclude or None can_delete = self.can_delete and self.has_delete_permission(request, obj) defaults = { "form": self.form, "formset": self.formset, "fields": fields, "exclude": exclude, "formfield_callback": partial(self.formfield_for_dbfield, request=request), "extra": self.get_extra(request, obj, **kwargs), "min_num": self.get_min_num(request, obj, **kwargs), "max_num": self.get_max_num(request, obj, **kwargs), "can_delete": can_delete, } defaults.update(kwargs) base_model_form = defaults['form'] class DeleteProtectedModelForm(base_model_form): def hand_clean_DELETE(self): """ We don't validate the 'DELETE' field itself because on templates it's not rendered using the field information, but just using a generic "deletion_field" of the InlineModelAdmin. """ if self.cleaned_data.get(DELETION_FIELD_NAME, False): using = router.db_for_write(self._meta.model) collector = NestedObjects(using=using) if self.instance.pk is None: return collector.collect([self.instance]) if collector.protected: objs = [] for p in collector.protected: objs.append( # Translators: Model verbose name and instance representation, # suitable to be an item in a list. _('%(class_name)s %(instance)s') % { 'class_name': p._meta.verbose_name, 'instance': p} ) params = {'class_name': self._meta.model._meta.verbose_name, 'instance': self.instance, 'related_objects': get_text_list(objs, _('and'))} msg = _("Deleting %(class_name)s %(instance)s would require " "deleting the following protected related objects: " "%(related_objects)s") raise ValidationError(msg, code='deleting_protected', params=params) def is_valid(self): result = super(DeleteProtectedModelForm, self).is_valid() self.hand_clean_DELETE() return result defaults['form'] = DeleteProtectedModelForm if defaults['fields'] is None and not modelform_defines_fields(defaults['form']): defaults['fields'] = forms.ALL_FIELDS return modelformset_factory(self.model, **defaults)
def _get_form_factory_opts(self, request, obj=None, **kwargs): fieldsets = self.get_fieldsets(request, obj) if fieldsets: fields = flatten_fieldsets(fieldsets) else: fields = None if self.exclude is None: exclude = [] else: exclude = list(self.exclude) exclude.extend(self.get_readonly_fields(request, obj)) if self.exclude is None and hasattr( self.form, '_meta') and self.form._meta.exclude: # Take the custom ModelForm's Meta.exclude into account only if the # ModelAdmin doesn't define its own. exclude.extend(self.form._meta.exclude) # construct the form_opts from declared_fieldsets form_opts = self.app_form_opts.copy() if fields is not None: # put app_name prefixed fields into form_opts for f in fields: if '.' not in f: continue label, name = f.split('.') app_fields = form_opts.setdefault(label, {}).setdefault('fields', []) if name not in app_fields: app_fields.append(name) # .. and remove them from fields for the model form fields = [f for f in fields if '.' not in f] # do the same for exclude for f in exclude: if '.' not in f: continue label, name = f.split('.') app_fields = form_opts.setdefault(label, {}).setdefault('exclude', []) if name not in app_fields: app_fields.append(name) exclude = [f for f in exclude if '.' not in f] # if exclude is an empty list we pass None to be consistant with the # default on modelform_factory exclude = exclude or None defaults = { "form": self.form, "multiform": self.multiform, "form_opts": form_opts, "fields": fields, "exclude": exclude, "formfield_callback": partial(self.formfield_for_dbfield, request=request), } defaults.update(kwargs) if hasattr(forms, 'ALL_FIELDS'): # Django 1.7 if defaults['fields'] is None and not modelform_defines_fields( defaults['form']): defaults['fields'] = forms.ALL_FIELDS return defaults