Changes between Initial Version and Version 1 of Ticket #33832, comment 2


Ignore:
Timestamp:
Jul 9, 2022, 6:45:56 AM (22 months ago)
Author:
ldeluigi

Legend:

Unmodified
Added
Removed
Modified
  • Ticket #33832, comment 2

    initial v1  
    1 If someone stumbles upon this I managed to fix my issue with this monkeypatch of [https://github.com/django/django/blob/eb3699ea775548a22e0407ad12bf8cbdeaf95ff5/django/contrib/admin/options.py#L1748]:
    2 
    3 {{{
    4 from django.contrib.admin.options import *
    5 from django.contrib.admin.exceptions import DisallowedModelAdminToField
    6 from django.core.exceptions import (
    7     PermissionDenied,
    8     ValidationError,
    9 )
    10 from django.contrib.admin.utils import (
    11     flatten_fieldsets,
    12     unquote,
    13 )
    14 from django.forms.formsets import all_valid
    15 from django.contrib.admin import helpers
    16 from django.utils.translation import gettext as _
    17 
    18 class NewModelAdmin(ModelAdmin):
    19     def _changeform_view(self, request, object_id, form_url, extra_context):
    20         to_field = request.POST.get(TO_FIELD_VAR, request.GET.get(TO_FIELD_VAR))
    21         if to_field and not self.to_field_allowed(request, to_field):
    22             raise DisallowedModelAdminToField(
    23                 "The field %s cannot be referenced." % to_field
    24             )
    25 
    26         model = self.model
    27         opts = model._meta
    28 
    29         if request.method == "POST" and "_saveasnew" in request.POST:
    30             object_id = None
    31 
    32         add = object_id is None
    33 
    34         if add:
    35             if not self.has_add_permission(request):
    36                 raise PermissionDenied
    37             obj = None
    38 
    39         else:
    40             obj = self.get_object(request, unquote(object_id), to_field)
    41 
    42             if request.method == "POST":
    43                 if not self.has_change_permission(request, obj):
    44                     raise PermissionDenied
    45             else:
    46                 if not self.has_view_or_change_permission(request, obj):
    47                     raise PermissionDenied
    48 
    49             if obj is None:
    50                 return self._get_obj_does_not_exist_redirect(request, opts, object_id)
    51 
    52         fieldsets = self.get_fieldsets(request, obj)
    53         ModelForm = self.get_form(
    54             request, obj, change=not add, fields=flatten_fieldsets(fieldsets)
    55         )
    56         if request.method == "POST":
    57             form = ModelForm(request.POST, request.FILES, instance=obj)
    58             formsets, inline_instances = self._create_formsets(
    59                 request,
    60                 form.instance if add else obj,
    61                 change=not add,
    62             )
    63             form_validated = form.is_valid()
    64             if form_validated:
    65                 new_object = self.save_form(request, form, change=not add)
    66             else:
    67                 new_object = form.instance
    68             if all_valid(formsets) and form_validated:
    69                 try:
    70                     self.save_model(request, new_object, form, not add)
    71                     self.save_related(request, form, formsets, not add)
    72                     change_message = self.construct_change_message(
    73                     request, form, formsets, add
    74                     )
    75                     if add:
    76                         self.log_addition(request, new_object, change_message)
    77                         return self.response_add(request, new_object)
    78                     else:
    79                         self.log_change(request, new_object, change_message)
    80                         return self.response_change(request, new_object)
    81                 except ValidationError as e:
    82                     form_validated = False
    83                     form._update_errors([e])
    84             else:
    85                 form_validated = False
    86         else:
    87             if add:
    88                 initial = self.get_changeform_initial_data(request)
    89                 form = ModelForm(initial=initial)
    90                 formsets, inline_instances = self._create_formsets(
    91                     request, form.instance, change=False
    92                 )
    93             else:
    94                 form = ModelForm(instance=obj)
    95                 formsets, inline_instances = self._create_formsets(
    96                     request, obj, change=True
    97                 )
    98 
    99         if not add and not self.has_change_permission(request, obj):
    100             readonly_fields = flatten_fieldsets(fieldsets)
    101         else:
    102             readonly_fields = self.get_readonly_fields(request, obj)
    103         adminForm = helpers.AdminForm(
    104             form,
    105             list(fieldsets),
    106             # Clear prepopulated fields on a view-only form to avoid a crash.
    107             self.get_prepopulated_fields(request, obj)
    108             if add or self.has_change_permission(request, obj)
    109             else {},
    110             readonly_fields,
    111             model_admin=self,
    112         )
    113         media = self.media + adminForm.media
    114 
    115         inline_formsets = self.get_inline_formsets(
    116             request, formsets, inline_instances, obj
    117         )
    118         for inline_formset in inline_formsets:
    119             media = media + inline_formset.media
    120 
    121         if add:
    122             title = _("Add %s")
    123         elif self.has_change_permission(request, obj):
    124             title = _("Change %s")
    125         else:
    126             title = _("View %s")
    127         context = {
    128             **self.admin_site.each_context(request),
    129             "title": title % opts.verbose_name,
    130             "subtitle": str(obj) if obj else None,
    131             "adminform": adminForm,
    132             "object_id": object_id,
    133             "original": obj,
    134             "is_popup": IS_POPUP_VAR in request.POST or IS_POPUP_VAR in request.GET,
    135             "to_field": to_field,
    136             "media": media,
    137             "inline_admin_formsets": inline_formsets,
    138             "errors": helpers.AdminErrorList(form, formsets),
    139             "preserved_filters": self.get_preserved_filters(request),
    140         }
    141 
    142         # Hide the "Save" and "Save and continue" buttons if "Save as New" was
    143         # previously chosen to prevent the interface from getting confusing.
    144         if (
    145             request.method == "POST"
    146             and not form_validated
    147             and "_saveasnew" in request.POST
    148         ):
    149             context["show_save"] = False
    150             context["show_save_and_continue"] = False
    151             # Use the change template instead of the add template.
    152             add = False
    153 
    154         context.update(extra_context or {})
    155 
    156         return self.render_change_form(
    157             request, context, add=add, change=not add, obj=obj, form_url=form_url
    158         )
    159 }}}
    160 
    161 
    162 using this modified ModelAdmin called NewModelAdmin will catch ValidationError(s) during the save process and properly handle those.
    163 
    164 
    165 My code overrides the entire method but changes only these lines:
    166 https://github.com/django/django/blob/eb3699ea775548a22e0407ad12bf8cbdeaf95ff5/django/contrib/admin/options.py#L1796-L1807
     1If someone stumbles upon this I managed to fix my issue with this:
     2https://forum.djangoproject.com/t/many-to-many-field-validation-in-django/14701/11
Back to Top