Esempio n. 1
0
 def _check_fk_name(self, cls, parent_model):
     try:
         _get_foreign_key(parent_model, cls.model, fk_name=cls.fk_name)
     except ValueError as e:
         return [checks.Error(e.args[0], hint=None, obj=cls, id="admin.E202")]
     else:
         return []
Esempio n. 2
0
 def _check_relation(self, obj, parent_model):
     try:
         _get_foreign_key(parent_model, obj.model, fk_name=obj.fk_name)
     except ValueError as e:
         return [checks.Error(e.args[0], hint=None, obj=obj.__class__, id='admin.E202')]
     else:
         return []
Esempio n. 3
0
 def _check_relation(self, obj, parent_model):
     try:
         _get_foreign_key(parent_model, obj.model, fk_name=obj.fk_name)
     except ValueError as e:
         return [checks.Error(e.args[0], obj=obj.__class__, id='admin.E202')]
     else:
         return []
Esempio n. 4
0
 def _check_relation(self, cls, parent_model):
     try:
         _get_foreign_key(parent_model, cls.model, fk_name=cls.fk_name)
     except ValueError as e:
         return [checks.Error(e.args[0], hint=None, obj=cls, id='admin.E202')]
     else:
         return []
Esempio n. 5
0
 def _check_fk_name(self, cls, parent_model):
     try:
         _get_foreign_key(parent_model, cls.model, fk_name=cls.fk_name)
     except ValueError as e:
         # Check if generic, if not add error.
         is_generic_inline_admin = any(
             isinstance(vf, GenericForeignKey) for vf in parent_model._meta.virtual_fields)
         if is_generic_inline_admin:
             return []
         return [checks.Error(e.args[0], hint=None, obj=cls, id='admin.E202')]
     else:
         return []
Esempio n. 6
0
def validate_inline(cls, parent, parent_model):

    # model is already verified to exist and be a Model
    if cls.fk_name: # default value is None
        f = get_field(cls, cls.model, cls.model._meta, 'fk_name', cls.fk_name)
        if not isinstance(f, models.ForeignKey):
            raise ImproperlyConfigured("'%s.fk_name is not an instance of "
                    "models.ForeignKey." % cls.__name__)

    fk = _get_foreign_key(parent_model, cls.model, fk_name=cls.fk_name, can_fail=True)

    # extra = 3
    if not isinstance(getattr(cls, 'extra'), int):
        raise ImproperlyConfigured("'%s.extra' should be a integer."
                % cls.__name__)

    # max_num = None
    max_num = getattr(cls, 'max_num', None)
    if max_num is not None and not isinstance(max_num, int):
        raise ImproperlyConfigured("'%s.max_num' should be an integer or None (default)."
                % cls.__name__)

    # formset
    if hasattr(cls, 'formset') and not issubclass(cls.formset, BaseModelFormSet):
        raise ImproperlyConfigured("'%s.formset' does not inherit from "
                "BaseModelFormSet." % cls.__name__)

    # exclude
    if hasattr(cls, 'exclude') and cls.exclude:
        if fk and fk.name in cls.exclude:
            raise ImproperlyConfigured("%s cannot exclude the field "
                    "'%s' - this is the foreign key to the parent model "
                    "%s." % (cls.__name__, fk.name, parent_model.__name__))
Esempio n. 7
0
    def _check_exclude_of_parent_model(self, cls, parent_model):
        # Do not perform more specific checks if the base checks result in an
        # error.
        errors = super(InlineModelAdminChecks,
                       self)._check_exclude(cls, parent_model)
        if errors:
            return []

        # Skip if `fk_name` is invalid.
        if self._check_relation(cls, parent_model):
            return []

        if cls.exclude is None:
            return []

        fk = _get_foreign_key(parent_model, cls.model, fk_name=cls.fk_name)
        if fk.name in cls.exclude:
            return [
                checks.Error(
                    "Cannot exclude the field '%s', because it is the foreign key "
                    "to the parent model '%s.%s'." %
                    (fk.name, parent_model._meta.app_label,
                     parent_model._meta.object_name),
                    hint=None,
                    obj=cls,
                    id='admin.E201',
                )
            ]
        else:
            return []
Esempio n. 8
0
    def __init__(self, **kw):
        #~ self.groups = [] # for later
        #~ self.totals = [] # for later
        if self.label is None:
            self.label = self.__class__.__name__
        if self.name is None:
            self.name = self.__class__.__name__.lower()
        #~ if self.title is None:
        #~ self.title = self.build_title()
        #~ if self.queryset is None:
        #~ self.queryset = self.get_queryset()
        if self.model is None:
            self.model = self.queryset.model
        if self.form_class is None:
            self.form_class = modelform_factory(self.model)
        if self.row_layout_class is None:
            self.row_layout = layouts.RowLayout(self.model, self.columnNames)
        else:
            assert self.columnNames is None
            self.row_layout = self.row_layout_class(self.model)
        if self.master:
            self.fk = _get_foreign_key(self.master, self.model, self.fk_name)
        self._page_layouts = [
            layout(self.model) for layout in self.page_layouts
        ]

        for k, v in kw.items():
            if not hasattr(self, k):
                print "[Warning] Ignoring attribute %s" % k
            setattr(self, k, v)
Esempio n. 9
0
    def _check_exclude_of_parent_model(self, obj, parent_model):
        # Do not perform more specific checks if the base checks result in an
        # error.
        errors = super(InlineModelAdminChecks, self)._check_exclude(obj)
        if errors:
            return []

        # Skip if `fk_name` is invalid.
        if self._check_relation(obj, parent_model):
            return []

        if obj.exclude is None:
            return []

        fk = _get_foreign_key(parent_model, obj.model, fk_name=obj.fk_name)
        if fk.name in obj.exclude:
            return [
                checks.Error(
                    "Cannot exclude the field '%s', because it is the foreign key "
                    "to the parent model '%s.%s'." % (
                        fk.name, parent_model._meta.app_label, parent_model._meta.object_name
                    ),
                    hint=None,
                    obj=obj.__class__,
                    id='admin.E201',
                )
            ]
        else:
            return []
Esempio n. 10
0
 def __init__(self,**kw):
     #~ self.groups = [] # for later
     #~ self.totals = [] # for later
     if self.label is None:
         self.label = self.__class__.__name__
     if self.name is None:
         self.name = self.__class__.__name__.lower()
     #~ if self.title is None:
         #~ self.title = self.build_title()
     #~ if self.queryset is None:
         #~ self.queryset = self.get_queryset()
     if self.model is None:
         self.model = self.queryset.model
     if self.form_class is None:
         self.form_class = modelform_factory(self.model)
     if self.row_layout_class is None:
         self.row_layout = layouts.RowLayout(self.model,
                                             self.columnNames)
     else:
         assert self.columnNames is None
         self.row_layout = self.row_layout_class(self.model)
     if self.master:
         self.fk = _get_foreign_key(self.master,
           self.model,self.fk_name)
     self._page_layouts = [
           layout(self.model) for layout in self.page_layouts]
             
     for k,v in kw.items():
         if not hasattr(self,k):
             print "[Warning] Ignoring attribute %s" % k
         setattr(self,k,v)
 def _get_list_filter(self):
     list_filter = super(InlineTableView, self)._get_list_filter()
     fk_name = _get_foreign_key(self.parent_instance.__class__, self.model, fk_name=self.fk_name).name
     list_filter['filter'] = filter = list_filter.get('filter', {})
     if 'filter' in list_filter:
         filter[fk_name] = self.parent_instance.pk
     return list_filter
 def get_formsets(self, request, obj=None):
     initial = {}
     model = self.model
     opts = model._meta
     data = getattr(request, request.method).items()
     # If an object is provided we collect data
     if obj is not None:
         initial.update(model_to_dict(obj))
     # Make sure to collect parent model data
     # and provide it to fieldsets in the form of
     # parent__field from request if its provided.
     # This data should be more "up-to-date".
     for k, v in data:
         if v:
             try:
                 f = opts.get_field(k)
             except models.FieldDoesNotExist:
                 continue
             if isinstance(f, models.ManyToManyField):
                 initial[k] = v.split(",")
             else:
                 initial[k] = v
     for formset, inline in zip(super(cls, self).get_formsets(request, obj), self.inline_instances):
         fk = _get_foreign_key(self.model, inline.model, fk_name=inline.fk_name).name
         fk_initial = dict(('%s__%s' % (fk, k),v) for k, v in initial.iteritems())
         # If we must provide additional data
         # we must wrap the formset in a subclass
         # because passing 'initial' key argument is intercepted
         # and not provided to subclasses by BaseInlineFormSet.__init__
         if len(initial):
             formset = dynamic_formset_factory(formset, fk_initial)
         yield formset
Esempio n. 13
0
 def _get_list_filter(self):
     list_filter = super(InlineTableView, self)._get_list_filter()
     fk_name = _get_foreign_key(self.parent_instance.__class__, self.model, fk_name=self.fk_name).name
     list_filter['filter'] = filter = list_filter.get('filter', {})
     if 'filter' in list_filter:
         filter[fk_name] = self.parent_instance.pk
     return list_filter
Esempio n. 14
0
    def _check_exclude_of_parent_model(self, cls, parent_model):
        # Do not perform more specific checks if the base checks result in an
        # error.
        errors = super(InlineModelAdminChecks, self)._check_exclude(cls, parent_model)
        if errors:
            return []

        # Skip if `fk_name` is invalid.
        if self._check_fk_name(cls, parent_model):
            return []

        if cls.exclude is None:
            return []

        fk = _get_foreign_key(parent_model, cls.model, fk_name=cls.fk_name)
        if fk.name in cls.exclude:
            return [
                checks.Error(
                    'Cannot exclude the field "%s", because it is the foreign key '
                    "to the parent model %s.%s."
                    % (fk.name, parent_model._meta.app_label, parent_model._meta.object_name),
                    hint=None,
                    obj=cls,
                    id="admin.E201",
                )
            ]
        else:
            return []
Esempio n. 15
0
def translatable_inlineformset_factory(language, parent_model, model, form=TranslatableModelForm,
                          formset=BaseInlineFormSet, fk_name=None,
                          fields=None, exclude=None,
                          extra=3, can_order=False, can_delete=True, max_num=None,
                          formfield_callback=None):
    """
    Returns an ``InlineFormSet`` for the given kwargs.

    You must provide ``fk_name`` if ``model`` has more than one ``ForeignKey``
    to ``parent_model``.
    """
    from django.forms.models import _get_foreign_key
    fk = _get_foreign_key(parent_model, model, fk_name=fk_name)
    # enforce a max_num=1 when the foreign key to the parent model is unique.
    if fk.unique:
        max_num = 1
    kwargs = {
        'form': form,
        'formfield_callback': formfield_callback,
        'formset': formset,
        'extra': extra,
        'can_delete': can_delete,
        'can_order': can_order,
        'fields': fields,
        'exclude': exclude,
        'max_num': max_num,
    }
    FormSet = translatable_modelformset_factory(language, model, **kwargs)
    FormSet.fk = fk
    return FormSet
Esempio n. 16
0
def translatable_inlineformset_factory(language, parent_model, model, form=TranslatableModelForm,
                          formset=BaseInlineFormSet, fk_name=None,
                          fields=None, exclude=None,
                          extra=3, can_order=False, can_delete=True, max_num=None,
                          formfield_callback=None):
    """
    Returns an ``InlineFormSet`` for the given kwargs.

    You must provide ``fk_name`` if ``model`` has more than one ``ForeignKey``
    to ``parent_model``.
    """
    from django.forms.models import _get_foreign_key
    fk = _get_foreign_key(parent_model, model, fk_name=fk_name)
    # enforce a max_num=1 when the foreign key to the parent model is unique.
    if fk.unique:
        max_num = 1
    kwargs = {
        'form': form,
        'formfield_callback': formfield_callback,
        'formset': formset,
        'extra': extra,
        'can_delete': can_delete,
        'can_order': can_order,
        'fields': fields,
        'exclude': exclude,
        'max_num': max_num,
    }
    FormSet = translatable_modelformset_factory(language, model, **kwargs)
    FormSet.fk = fk
    return FormSet
Esempio n. 17
0
 def get_form_exclude(self, request, obj=None):
     exclude = super(ViaRestModelISCore, self).get_form_exclude(request, obj)
     if obj:
         fk = _get_foreign_key(self.via_model, self.model, fk_name=self.fk_name).name
         exclude = list(exclude)
         exclude.append(fk)
     return exclude
Esempio n. 18
0
    def _check_exclude_of_parent_model(self, obj, parent_model):
        # Do not perform more specific checks if the base checks result in an
        # error.
        errors = super()._check_exclude(obj)
        if errors:
            return []

        # Skip if `fk_name` is invalid.
        if self._check_relation(obj, parent_model):
            return []

        if obj.exclude is None:
            return []

        fk = _get_foreign_key(parent_model, obj.model, fk_name=obj.fk_name)
        if fk.name in obj.exclude:
            return [
                checks.Error(
                    "Cannot exclude the field '%s', because it is the foreign key "
                    "to the parent model '%s.%s'." %
                    (fk.name, parent_model._meta.app_label,
                     parent_model._meta.object_name),
                    obj=obj.__class__,
                    id='admin.E201',
                )
            ]
        else:
            return []
Esempio n. 19
0
def translatable_inlineformset_factory(language,
                                       parent_model,
                                       model,
                                       form=TranslatableModelForm,
                                       formset=BaseInlineFormSet,
                                       fk_name=None,
                                       fields=None,
                                       exclude=None,
                                       extra=3,
                                       can_order=False,
                                       can_delete=True,
                                       max_num=None,
                                       formfield_callback=None,
                                       **kwargs):
    from django.forms.models import _get_foreign_key
    fk = _get_foreign_key(parent_model, model, fk_name=fk_name)
    if fk.unique:  #pragma: no cover (internal Django behavior)
        max_num = 1

    FormSet = translatable_modelformset_factory(
        language,
        model,
        form=form,
        formfield_callback=formfield_callback,
        formset=formset,
        extra=extra,
        can_delete=can_delete,
        can_order=can_order,
        fields=fields,
        exclude=exclude,
        max_num=max_num,
        **kwargs)
    FormSet.fk = fk
    return FormSet
Esempio n. 20
0
def childformset_factory(parent_model, model, form=ModelForm,
    formset=BaseChildFormSet, fk_name=None, fields=None, exclude=None,
    extra=3, can_order=False, can_delete=True, max_num=None, validate_max=False,
    formfield_callback=None, widgets=None, min_num=None, validate_min=False):

    fk = _get_foreign_key(parent_model, model, fk_name=fk_name)
    # enforce a max_num=1 when the foreign key to the parent model is unique.
    if fk.unique:
        max_num = 1
        validate_max = True

    if exclude is None:
        exclude = []
    exclude += [fk.name]

    kwargs = {
        'form': form,
        'formfield_callback': formfield_callback,
        'formset': formset,
        'extra': extra,
        'can_delete': can_delete,
        # if the model supplies a sort_order_field, enable ordering regardless of
        # the current setting of can_order
        'can_order': (can_order or hasattr(model, 'sort_order_field')),
        'fields': fields,
        'exclude': exclude,
        'max_num': max_num,
        'validate_max': validate_max,
        'widgets': widgets,
        'min_num': min_num,
        'validate_min': validate_min,
    }
    FormSet = transientmodelformset_factory(model, **kwargs)
    FormSet.fk = fk
    return FormSet
Esempio n. 21
0
 def check_inline(self, cls, parent_model):
     " Validate inline class's fk field is not excluded. "
     fk = _get_foreign_key(parent_model, cls.model, fk_name=cls.fk_name, can_fail=True)
     if hasattr(cls, 'exclude') and cls.exclude:
         if fk and fk.name in cls.exclude:
             raise ImproperlyConfigured("%s cannot exclude the field "
                     "'%s' - this is the foreign key to the parent model "
                     "%s.%s." % (cls.__name__, fk.name, parent_model._meta.app_label, parent_model.__name__))
Esempio n. 22
0
 def get_formset(self, request, obj=None):
     setattr(self.form, '_magic_user', request.user) # magic variable assigned to form
     setattr(self, '_magic_user', request.user) # magic variable
     from django.forms.models import _get_foreign_key
     setattr(self, '_magic_instance', obj)
     setattr(self, '_magic_fk', _get_foreign_key(self.parent_model, self.model, fk_name=self.fk_name))
     self.user = request.user
     return super(NewmanInlineModelAdmin, self).get_formset(request, obj)
Esempio n. 23
0
def multiinlineformset_factory(parent_model, model, multiform=MultiForm, app_data_field='app_data', name=None, form_opts={},
                                formset=BaseInlineFormSet, fk_name=None, **kwargs):
    fk = _get_foreign_key(parent_model, model, fk_name=fk_name)
    if fk.unique:
        kwargs['max_num'] = 1
    FormSet = multiformset_factory(model, multiform, app_data_field, name, form_opts, formset=formset, **kwargs)
    FormSet.fk = fk
    return FormSet
Esempio n. 24
0
 def check_inline(self, cls, parent_model):
     " Validate inline class's fk field is not excluded. "
     fk = _get_foreign_key(parent_model, cls.model, fk_name=cls.fk_name, can_fail=True)
     if hasattr(cls, 'exclude') and cls.exclude:
         if fk and fk.name in cls.exclude:
             raise ImproperlyConfigured("%s cannot exclude the field "
                     "'%s' - this is the foreign key to the parent model "
                     "%s.%s." % (cls.__name__, fk.name, parent_model._meta.app_label, parent_model.__name__))
Esempio n. 25
0
def multiinlineformset_factory(parent_model, model, multiform=MultiForm, app_data_field='app_data', name=None, form_opts={},
                                formset=BaseInlineFormSet, fk_name=None, **kwargs):
    fk = _get_foreign_key(parent_model, model, fk_name=fk_name)
    if fk.unique:
        kwargs['max_num'] = 1
    FormSet = multiformset_factory(model, multiform, app_data_field, name, form_opts, formset=formset, **kwargs)
    FormSet.fk = fk
    return FormSet
Esempio n. 26
0
 def post_register(self):
     from django.db.models.fields.related import RelatedObject
     from django.forms.models import _get_foreign_key
     self.fk = _get_foreign_key(self._parent.resource_adaptor, self.model, self.fk_name)
     if self.rel_name is None:
         #TODO invert this
         self.rel_name = RelatedObject(self.fk.rel.to, self.model, self.fk).get_accessor_name()
     super(InlineModelResource, self).post_register()
Esempio n. 27
0
    def __init__(self, parent_model, parent_admin):
        self.parent_model = parent_model
        self.parent_admin = parent_admin

        if self.fk_name is None:
            self.fk_name = _get_foreign_key(parent_model, self.model).name

        super(NestedAdminInitMixin, self).__init__(self.model, parent_admin.admin_site)
Esempio n. 28
0
 def post_register(self):
     from django.db.models.fields.related import RelatedObject
     from django.forms.models import _get_foreign_key
     self.fk = _get_foreign_key(self._parent.resource_adaptor, self.model,
                                self.fk_name)
     if self.rel_name is None:
         #TODO invert this
         self.rel_name = RelatedObject(self.fk.rel.to, self.model,
                                       self.fk).get_accessor_name()
     super(InlineModelResource, self).post_register()
Esempio n. 29
0
    def __init__(self, parent_model, parent_admin):
        self.parent_model = parent_model
        self.parent_admin = parent_admin

        if self.fk_name is None:
            self.fk_name = _get_foreign_key(parent_model, self.model).name

        super().__init__(self.model, parent_admin.admin_site)

        self.subadmin_instances = self.get_subadmin_instances()
Esempio n. 30
0
def validate_compose(cls, parent, parent_model):

    # model is already verified to exist and be a Model
    if cls.fk_name: # default value is None
        f = get_field(cls, cls.model, cls.model._meta, 'fk_name', cls.fk_name)
        if not isinstance(f, models.ForeignKey):
            raise ImproperlyConfigured("'%s.fk_name is not an instance of "
                    "models.ForeignKey." % cls.__name__)

    fk = _get_foreign_key(parent_model, cls.model, fk_name=cls.fk_name, can_fail=True)
Esempio n. 31
0
 def get_form_exclude(self, request, obj=None):
     exclude = super(ViaRESTModelISCore,
                     self).get_form_exclude(request, obj)
     if obj:
         fk = _get_foreign_key(self.via_model,
                               self.model,
                               fk_name=self.fk_name).name
         exclude = list(exclude)
         exclude.append(fk)
     return exclude
Esempio n. 32
0
def _get_all_admin_fields(request):
    request.data_browser = {"calculated_fields": set(), "fields": set()}

    def from_fieldsets(admin, all_):
        auth_user_compat = settings.DATA_BROWSER_AUTH_USER_COMPAT
        if auth_user_compat and isinstance(admin, UserAdmin):
            obj = admin.model()  # get the change fieldsets, not the add ones
        else:
            obj = None

        for f in flatten_fieldsets(admin.get_fieldsets(request, obj)):
            # skip calculated fields on inlines
            if not isinstance(admin, InlineModelAdmin) or hasattr(
                    admin.model, f):
                yield f

    def visible(model_admin, request):
        if model_admin.has_change_permission(request):
            return True
        if hasattr(model_admin, "has_view_permission"):
            return model_admin.has_view_permission(request)
        else:
            return False  # pragma: no cover  Django < 2.1

    all_admin_fields = defaultdict(set)
    model_admins = {}
    for model, model_admin in site._registry.items():
        model_admins[model] = model_admin
        if visible(model_admin, request):
            all_admin_fields[model].update(from_fieldsets(model_admin, True))
            all_admin_fields[model].update(
                model_admin.get_list_display(request))
            all_admin_fields[model].add(_OPEN_IN_ADMIN)

            # check the inlines, these are already filtered for access
            for inline in model_admin.get_inline_instances(request):
                try:
                    fk_field = _get_foreign_key(model, inline.model,
                                                inline.fk_name)
                except Exception:
                    pass  # ignore things like GenericInlineModelAdmin
                else:
                    if inline.model not in model_admins:  # pragma: no branch
                        model_admins[inline.model] = inline
                    all_admin_fields[inline.model].update(
                        from_fieldsets(inline, False))
                    all_admin_fields[inline.model].add(fk_field.name)

    # we always have id and never pk
    for fields in all_admin_fields.values():
        fields.add("id")
        fields.discard("pk")
        fields.discard("__str__")

    return model_admins, all_admin_fields
Esempio n. 33
0
 def __init__(self, parent_resource):
     self.resource_adaptor = self.model
     self.site = parent_resource.site
     self.parent_resource = parent_resource
     
     from django.db.models.fields.related import RelatedObject
     from django.forms.models import _get_foreign_key
     self.fk = _get_foreign_key(self.parent_resource.resource_adaptor, self.model, self.fk_name)
     if self.rel_name is None:
         self.rel_name = RelatedObject(self.fk.rel.to, self.model, self.fk).get_accessor_name()
     self.inline_instances = []
Esempio n. 34
0
def smartinlineformset_factory(parent_model,
                               model,
                               request,
                               form=ModelForm,
                               formset=BaseInlineFormSet,
                               fk_name=None,
                               fields=None,
                               exclude=None,
                               extra=3,
                               can_order=False,
                               can_delete=True,
                               min_num=None,
                               max_num=None,
                               formfield_callback=None,
                               widgets=None,
                               validate_min=False,
                               validate_max=False,
                               localized_fields=None,
                               labels=None,
                               help_texts=None,
                               error_messages=None,
                               formreadonlyfield_callback=None,
                               readonly_fields=None,
                               readonly=False):
    fk = _get_foreign_key(parent_model, model, fk_name=fk_name)
    # enforce a max_num=1 when the foreign key to the parent model is unique.
    if fk.unique:
        max_num = 1
    kwargs = {
        'form': form,
        'formfield_callback': formfield_callback,
        'formset': formset,
        'extra': extra,
        'can_delete': can_delete,
        'can_order': can_order,
        'fields': fields,
        'exclude': exclude,
        'max_num': max_num,
        'min_num': min_num,
        'widgets': widgets,
        'validate_max': validate_max,
        'validate_min': validate_min,
        'localized_fields': localized_fields,
        'labels': labels,
        'help_texts': help_texts,
        'error_messages': error_messages,
        'formreadonlyfield_callback': formreadonlyfield_callback,
        'readonly_fields': readonly_fields,
        'readonly': readonly,
    }
    FormSet = smartmodelformset_factory(model, request, **kwargs)
    FormSet.fk = fk
    return FormSet
Esempio n. 35
0
    def process(self):
        target = self.cleaned_data["target"]
        fields = []

        for field in self.instance._meta.get_fields():
            if self.cleaned_data.get("set_{}".format(field.name)):
                setattr(target, field.name, getattr(self.instance, field.name))
                fields.append("{}".format(
                    getattr(field, "verbose_name", field.name)))

        if fields:
            self.modeladmin.message_user(
                self.request,
                _("Updated fields of %(node)s: %(fields)s") % {
                    "node": target,
                    "fields": ", ".join(fields)
                },
            )

        if self.cleaned_data.get("_set_content"):
            from django.forms.models import _get_foreign_key  # Since 2009.

            for inline in self.modeladmin.inlines:
                fk = _get_foreign_key(self.modeladmin.model, inline.model,
                                      inline.fk_name, False)

                # Remove all existing instances
                inline.model._default_manager.filter(**{
                    fk.name: target
                }).delete()

                for obj in inline.model._default_manager.filter(
                        **{fk.name: self.instance}):
                    obj.pk = None
                    setattr(obj, fk.name, target)
                    obj.save(force_insert=True)

            self.modeladmin.message_user(
                self.request,
                _("Replaced the content of %(target)s with the contents of %(source)s."
                  ) % {
                      "target": target,
                      "source": self.instance
                  },
            )

        target.save()

        opts = self.modeladmin.model._meta
        return redirect(
            "admin:%s_%s_change" % (opts.app_label, opts.model_name),
            target.pk)
Esempio n. 36
0
File: options.py Progetto: whit/ella
 def get_formset(self, request, obj=None):
     setattr(self.form, '_magic_user',
             request.user)  # magic variable assigned to form
     setattr(self, '_magic_user', request.user)  # magic variable
     from django.forms.models import _get_foreign_key
     setattr(self, '_magic_instance', obj)
     setattr(
         self, '_magic_fk',
         _get_foreign_key(self.parent_model,
                          self.model,
                          fk_name=self.fk_name))
     self.user = request.user
     return super(NewmanInlineModelAdmin, self).get_formset(request, obj)
Esempio n. 37
0
def get_model_form(base_model=None,
                   base_form=None,
                   inline_models=None,
                   inline_forms=None,
                   inline_options=None,
                   common_options=None,
                   formset=False,
                   **kwargs):
    """
    Permet de construire d'un coup un formulaire de modèle et ses sous-formulaires éventuels
    Les listes `inline_models`, `inline_forms` et `inline_kwargs` doivent être de même taille et dans le même ordre
    :param base_model: Modèle de base (obligatoire)
    :param base_form: Formulaire pour le modèle de base (facultatif)
    :param inline_models: Sous-modèles à relier (obligatoire)
    :param inline_forms: Sous-formulaires pour chaque sous-modèle (facultatif)
    :param inline_options: Paramètres de chaque sous-formulaire (facultatif)
    :param formset: En faire un ensemble de formulaires ?
    :param kwargs: Paramètres optionnels utilisés uniquement pour le formulaire principal
    :return: Formulaire principal et ses sous-formulaires
    """
    from itertools import zip_longest
    common_options = common_options or {}
    inline_models, inline_forms, inline_options = inline_models or [], inline_forms or [], inline_options or []
    inlines = []
    for model, form, options in zip_longest(inline_models,
                                            inline_forms,
                                            inline_options,
                                            fillvalue=None):
        if not model:
            continue
        options = options or {}
        options.update(common_options)
        fk = _get_foreign_key(base_model, model)
        if fk.unique:
            options['max_num'] = 1
        inline = get_model_formset(model,
                                   form=form,
                                   formset=CommonInlineFormSet,
                                   **options)
        inline.fk = fk
        inlines.append(inline)
    if formset:
        formset = get_model_formset(base_model, form=base_form, **kwargs)
        formset._inlines = inlines
        return formset
    elif not base_form:
        base_form = modelform_factory(base_model,
                                      form=CommonModelForm,
                                      **kwargs)
    base_form._inlines = inlines
    return base_form
Esempio n. 38
0
 def set_parent_info(self, parent_model=None, fk_name=None):
     # TODO: should use property on parent_model
     self.parent_model = parent_model
     if self.parent_model:
         if self.is_generic_fk:
             # Generic FK (GenericRelation)
             field = get_generic_fk_field(self.model)
             if field:
                 self.fk_field = field.fk_field
                 self.ct_field = field.ct_field
         else:
             # Normal FK
             fk = _get_foreign_key(self.parent_model, self.model, fk_name)
             self.fk_name = fk.name
Esempio n. 39
0
 def get_inline_formsets(self, obj, change):
     "Helper function to generate InlineFormSets for add/change_view."
     inline_formsets = []
     obj = obj if change else None
     fields = flatten_fieldsets(self.get_fieldsets(self.mode))
     for InlineFormSet, inline in self.get_formsets_with_inlines(obj):
         inline_fk_field = _get_foreign_key(self.model, inline.model,
                                            inline.fk_name)
         if inline_fk_field.remote_field.name not in fields:
             continue
         formset_kwargs = inline.get_formset_kwargs(
             formset_class=InlineFormSet, obj=obj)
         inline_formsets.append(InlineFormSet(**formset_kwargs))
     return inline_formsets
Esempio n. 40
0
    def get_form_class(self, request, instance=None, **kwargs):
        kwargs.update(self.form_kwargs)
        if "exclude" in self.formset_kwargs:
            kwargs['exclude'] = kwargs.get("exclude", []) \
                + self.formset_kwargs.get("exclude")

        try:
            fk = _get_foreign_key(type(self.instance), self.model)
            kwargs['exclude'] = kwargs.get("exclude", []) + [fk.name]
        except:
            pass

        return modelform_factory(self.model,
                                 form=self.form_class or ModelForm,
                                 **kwargs)
Esempio n. 41
0
def translatable_inlineformset_factory(language, parent_model, model, form=TranslatableModelForm,
                                       formset=BaseInlineFormSet, fk_name=None,
                                       fields=None, exclude=None, extra=3,
                                       can_order=False, can_delete=True,
                                       max_num=None, formfield_callback=None, **kwargs):
    from django.forms.models import _get_foreign_key
    fk = _get_foreign_key(parent_model, model, fk_name=fk_name)
    if fk.unique:  #pragma: no cover (internal Django behavior)
        max_num = 1

    FormSet = translatable_modelformset_factory(language, model,
         form=form, formfield_callback=formfield_callback, formset=formset,
         extra=extra, can_delete=can_delete, can_order=can_order,
         fields=fields, exclude=exclude, max_num=max_num, **kwargs)
    FormSet.fk = fk
    return FormSet
Esempio n. 42
0
 def get_initial_inlines(self):
     initial_inlines = {}
     if self.request.GET.get('pk_copy', None) is not None:
         object_to_copy = get_object_or_404(self.get_queryset(),
                                            pk=self.request.GET['pk_copy'])
         for inline, inline_copy_fields in self.get_inlines_copy_fields(
         ).items():
             fields_to_copy = inline_copy_fields
             if inline.model._meta.pk.name in fields_to_copy:
                 fields_to_copy.remove(self.model._meta.pk.name)
             datas = []
             fk = _get_foreign_key(self.model, inline.model)
             for object in inline.model._default_manager.filter(
                     **{fk.name: object_to_copy}):
                 datas.append(model_to_dict(object, fields=fields_to_copy))
             initial_inlines.update({inline: datas})
     return initial_inlines
Esempio n. 43
0
def validate_inline(cls, parent, parent_model):

    # model is already verified to exist and be a Model
    if cls.fk_name:  # default value is None
        f = get_field(cls, cls.model, cls.model._meta, "fk_name", cls.fk_name)
        if not isinstance(f, models.ForeignKey):
            raise ImproperlyConfigured("'%s.fk_name is not an instance of "
                                       "models.ForeignKey." % cls.__name__)

    if not issubclass(cls, EmbeddedDocumentAdmin):
        fk = _get_foreign_key(parent_model,
                              cls.model,
                              fk_name=cls.fk_name,
                              can_fail=True)
    else:
        fk = None

    # extra = 3
    if not isinstance(cls.extra, int):
        raise ImproperlyConfigured("'%s.extra' should be a integer." %
                                   cls.__name__)

    # max_num = None
    max_num = getattr(cls, "max_num", None)
    if max_num is not None and not isinstance(max_num, int):
        raise ImproperlyConfigured(
            "'%s.max_num' should be an integer or None (default)." %
            cls.__name__)

    # formset
    if hasattr(cls,
               "formset") and not issubclass(cls.formset, BaseDocumentFormSet):
        raise ImproperlyConfigured("'%s.formset' does not inherit from "
                                   "BaseDocumentFormSet." % cls.__name__)

    # exclude
    if hasattr(cls, "exclude") and cls.exclude:
        if fk and fk.name in cls.exclude:
            raise ImproperlyConfigured(
                "%s cannot exclude the field "
                "'%s' - this is the foreign key to the parent model "
                "%s." % (cls.__name__, fk.name, parent_model.__name__))

    if hasattr(cls, "readonly_fields"):
        check_readonly_fields(cls, cls.document, cls.document._meta)
Esempio n. 44
0
def duplicate_page(original_page, page_changes=None):
    '''
        Takes a page and duplicates it as a child of the original's parent page.
        Expects to be passed the original page and an optional function
    '''
    from .admin import page_admin
    original_content = original_page.content

    with update_index():
        page = deepcopy(original_page)
        page.pk = None

        if callable(page_changes):
            page = page_changes(page, original_page)

        page.save()

        content = deepcopy(original_content)
        content.pk = None
        content.page = page
        content.save()

        # This doesn't copy m2m relations on the copied inline
        for content_cls, admin_cls in page_admin.content_inlines:
            if not isinstance(content, content_cls):
                continue

            model_cls = admin_cls.model
            fk = _get_foreign_key(Page, model_cls, fk_name=admin_cls.fk_name)

            related_items = model_cls.objects.filter(**{
                fk.name: original_page.pk
            }).distinct().all()
            for item in related_items:
                new_object = deepcopy(item)
                new_object.pk = None
                setattr(new_object, fk.name, page)
                new_object = overlay_obj(new_object,
                                         item,
                                         exclude=[fk.name, 'pk', 'id'],
                                         commit=True)
                new_object.save()

    return page
Esempio n. 45
0
def subform_factory(summary, items, included_fields=None):
    # TODO: fk_name may be necessary
    excludes = []
    try:
        fk = _get_foreign_key(summary.instance.__class__, items.rel_model, fk_name=None)
        excludes.append(fk.name)
    except Exception:
        pass
    # The following feature has been removed, in favour of explicit field selection
    # If this is an intermediate model, exclude the other foreign key field
    # if items.end_model is not None:
    #    efk = _get_foreign_key(items.end_model, items.rel_model, fk_name=None)
    #    excludes.append(efk.name)
    class Meta:
        model = items.rel_model
        exclude = excludes
        fields = included_fields

    return type("%sModelForm" % items.rel_model.__name__, (ModelForm,), {"Meta": Meta})
Esempio n. 46
0
def contenttype_inlineformset_factory(parent_model, model, admin_site,
                                      formfield_callback,
                                      extra=3, can_order=False,
                                      can_delete=True, max_num=0):
    fk = _get_foreign_key(parent_model, model)
    Meta = type('Meta', (MenuItemForm.Meta,), {'model': model})
    class_name = model.__name__ + 'Form'
    form_class_attrs = {
        'admin_site': admin_site,
        'Meta': Meta,
        'formfield_callback': formfield_callback
    }
    form = ModelFormMetaclass(class_name, (MenuItemForm,), form_class_attrs)
    FormSet = formset_factory(form, BaseInlineFormSet, extra=extra,
                              max_num=max_num,
                              can_order=can_order, can_delete=can_delete)
    FormSet.model = model
    FormSet.fk = fk
    return FormSet
Esempio n. 47
0
def contenttype_inlineformset_factory(parent_model, model, admin_site,
                                      formfield_callback,
                                      extra=3, can_order=False,
                                      can_delete=True, max_num=0):
    fk = _get_foreign_key(parent_model, model)
    Meta = type('Meta', (MenuItemForm.Meta,), {'model': model})
    class_name = model.__name__ + 'Form'
    form_class_attrs = {
        'admin_site': admin_site,
        'Meta': Meta,
        'formfield_callback': formfield_callback
    }
    form = ModelFormMetaclass(class_name, (MenuItemForm,), form_class_attrs)
    FormSet = formset_factory(form, BaseInlineFormSet, extra=extra,
                              max_num=max_num,
                              can_order=can_order, can_delete=can_delete)
    FormSet.model = model
    FormSet.fk = fk
    return FormSet
Esempio n. 48
0
    def form(self, parent, name, *args, **kwargs):
        form = self._get_or_load_from_module(self.form_name)

        fk = _get_foreign_key(self.model, parent._meta.model, name)

        Form = modelform_factory(
            self.model,
            form=form,
            fields=self.fields,
            exclude=self.exclude,
            formfield_callback=self.formfield_callback,
            widgets=self.widgets,
            localized_fields=self.localized_fields,
            labels=self.labels,
            help_texts=self.help_texts,
            error_messages=self.error_messages,
        )
        Form.fk = fk

        form_widget = Form(*args, **kwargs)
        return form_widget
Esempio n. 49
0
def subform_factory(summary, items, included_fields=None):
    # TODO: fk_name may be necessary
    excludes = []
    try:
        fk = _get_foreign_key(summary.instance.__class__,
                              items.rel_model,
                              fk_name=None)
        excludes.append(fk.name)
    except Exception:
        pass
    # The following feature has been removed, in favour of explicit field selection
    # If this is an intermediate model, exclude the other foreign key field
    #if items.end_model is not None:
    #    efk = _get_foreign_key(items.end_model, items.rel_model, fk_name=None)
    #    excludes.append(efk.name)
    class Meta:
        model = items.rel_model
        exclude = excludes
        fields = included_fields

    return type('%sModelForm' % items.rel_model.__name__, (ModelForm, ),
                {'Meta': Meta})
Esempio n. 50
0
        def get_formsets_with_inlines(self, request, obj=None):
            # Make sure to pass request data to fieldsets
            # so they can use it to define choices
            initial = {}
            model = self.model
            opts = model._meta
            data = getattr(request, request.method).items()
            # If an object is provided we collect data
            if obj is not None:
                initial.update(model_to_dict(obj))
            # Make sure to collect parent model data
            # and provide it to fieldsets in the form of
            # parent__field from request if its provided.
            # This data should be more "up-to-date".
            for k, v in data:
                if v:
                    try:
                        f = opts.get_field(k)
                    except models.FieldDoesNotExist:
                        continue
                    if isinstance(f, models.ManyToManyField):
                        initial[k] = v.split(",")
                    else:
                        initial[k] = v

            for formset, inline in self._get_formsets_with_inlines(
                    request, obj):
                fk = _get_foreign_key(self.model,
                                      inline.model,
                                      fk_name=inline.fk_name).name
                fk_initial = dict(
                    ('%s__%s' % (fk, k), v) for k, v in initial.items())
                # If we must provide additional data
                # we must wrap the formset in a subclass
                # because passing 'initial' key argument is intercepted
                # and not provided to subclasses by BaseInlineFormSet.__init__
                if len(initial):
                    formset = dynamic_formset_factory(formset, fk_initial)
                yield formset, inline
Esempio n. 51
0
def smartinlineformset_factory(parent_model, model, request, form=ModelForm,
                               formset=BaseInlineFormSet, fk_name=None,
                               fields=None, exclude=None, extra=3, can_order=False,
                               can_delete=True, min_num=None, max_num=None, formfield_callback=None,
                               widgets=None, validate_min=False, validate_max=False, localized_fields=None,
                               labels=None, help_texts=None, error_messages=None,
                               formreadonlyfield_callback=None, readonly_fields=None,
                               readonly=False):
    fk = _get_foreign_key(parent_model, model, fk_name=fk_name)
    # enforce a max_num=1 when the foreign key to the parent model is unique.
    if fk.unique:
        max_num = 1
    kwargs = {
        'form': form,
        'formfield_callback': formfield_callback,
        'formset': formset,
        'extra': extra,
        'can_delete': can_delete,
        'can_order': can_order,
        'fields': fields,
        'exclude': exclude,
        'max_num': max_num,
        'min_num': min_num,
        'widgets': widgets,
        'validate_max': validate_max,
        'validate_min': validate_min,
        'localized_fields': localized_fields,
        'labels': labels,
        'help_texts': help_texts,
        'error_messages': error_messages,
        'formreadonlyfield_callback': formreadonlyfield_callback,
        'readonly_fields': readonly_fields,
        'readonly': readonly,
    }
    FormSet = smartmodelformset_factory(model, request, **kwargs)
    FormSet.fk = fk
    return FormSet
Esempio n. 52
0
def validate_inline(cls, parent, parent_model):

    # model is already verified to exist and be a Model
    if cls.fk_name:  # default value is None
        f = get_field(cls, cls.model, cls.model._meta, "fk_name", cls.fk_name)
        if not isinstance(f, models.ForeignKey):
            raise ImproperlyConfigured("'%s.fk_name is not an instance of " "models.ForeignKey." % cls.__name__)

    if not issubclass(cls, EmbeddedDocumentAdmin):
        fk = _get_foreign_key(parent_model, cls.model, fk_name=cls.fk_name, can_fail=True)
    else:
        fk = None

    # extra = 3
    if not isinstance(cls.extra, int):
        raise ImproperlyConfigured("'%s.extra' should be a integer." % cls.__name__)

    # max_num = None
    max_num = getattr(cls, "max_num", None)
    if max_num is not None and not isinstance(max_num, int):
        raise ImproperlyConfigured("'%s.max_num' should be an integer or None (default)." % cls.__name__)

    # formset
    if hasattr(cls, "formset") and not issubclass(cls.formset, BaseDocumentFormSet):
        raise ImproperlyConfigured("'%s.formset' does not inherit from " "BaseDocumentFormSet." % cls.__name__)

    # exclude
    if hasattr(cls, "exclude") and cls.exclude:
        if fk and fk.name in cls.exclude:
            raise ImproperlyConfigured(
                "%s cannot exclude the field "
                "'%s' - this is the foreign key to the parent model "
                "%s." % (cls.__name__, fk.name, parent_model.__name__)
            )

    if hasattr(cls, "readonly_fields"):
        check_readonly_fields(cls, cls.document, cls.document._meta)
Esempio n. 53
0
def inlineformset_factory(parent_model,
                          model,
                          extra=3,
                          max_num=None,
                          fk_name=None,
                          formset=BaseInlineFormSet,
                          **kwargs):
    """
    Returns an ``InlineFormSet`` for the given kwargs.

    You must provide ``fk_name`` if ``model`` has more than one ``ForeignKey``
    to ``parent_model``.
    """
    # enforce a max_num=1 when the foreign key to the parent model is unique.
    fk = _get_foreign_key(parent_model, model, fk_name=fk_name)
    if fk.unique:
        max_num = 1
    FormSet = modelformset_factory(model,
                                   formset=formset,
                                   max_num=max_num,
                                   extra=extra,
                                   **kwargs)
    FormSet.fk = fk
    return FormSet
 def _get_list_filter(self):
     fk_name = _get_foreign_key(self.parent_instance.__class__, self.model, fk_name=self.fk_name).name
     return {'filter': {fk_name: self.parent_instance.pk}}
Esempio n. 55
0
def _get_all_admin_fields(request):
    request.data_browser = {"calculated_fields": set(), "fields": set()}

    def from_fieldsets(admin, all_):
        auth_user_compat = settings.DATA_BROWSER_AUTH_USER_COMPAT
        if auth_user_compat and isinstance(admin, UserAdmin):
            obj = admin.model()  # get the change fieldsets, not the add ones
        else:
            obj = None

        fields = admin.get_fieldsets(request, obj)
        for f in flatten_fieldsets(fields):
            # skip calculated fields on inlines
            if not isinstance(admin, InlineModelAdmin) or hasattr(
                    admin.model, f):
                yield f

    def visible(model_admin, request):
        attrs = ["get_fieldsets", "model", "get_queryset"]
        if not all(hasattr(model_admin, a) for a in attrs):
            debug_log(
                f"{type(model_admin)} instance does not look like a ModelAdmin or InlineModelAdmin"
            )
            return False
        if getattr(model_admin, "ddb_ignore", False):
            return False
        if model_admin.has_change_permission(request):
            return True
        if hasattr(model_admin, "has_view_permission"):
            return model_admin.has_view_permission(request)
        else:
            return False  # pragma: no cover  Django < 2.1

    all_admin_fields = defaultdict(set)
    hidden_fields = defaultdict(set)
    model_admins = {}
    for model, model_admin in site._registry.items():
        model_admins[model] = model_admin
        if visible(model_admin, request):
            all_admin_fields[model].update(from_fieldsets(model_admin, True))
            all_admin_fields[model].update(
                model_admin.get_list_display(request))
            all_admin_fields[model].update(
                getattr(model_admin, "ddb_extra_fields", []))
            all_admin_fields[model].add(open_in_admin)
            hidden_fields[model].update(
                getattr(model_admin, "ddb_hide_fields", []))

            # check the inlines, these are already filtered for access
            for inline in model_admin.get_inline_instances(request):
                if visible(inline, request):
                    try:
                        fk_field = _get_foreign_key(model, inline.model,
                                                    inline.fk_name)
                    except Exception as e:
                        debug_log(
                            e)  # ignore things like GenericInlineModelAdmin
                    else:
                        if inline.model not in model_admins:  # pragma: no branch
                            model_admins[inline.model] = inline
                        all_admin_fields[inline.model].update(
                            from_fieldsets(inline, False))
                        all_admin_fields[inline.model].update(
                            getattr(inline, "ddb_extra_fields", []))
                        all_admin_fields[inline.model].add(fk_field.name)
                        hidden_fields[inline.model].update(
                            getattr(inline, "ddb_hide_fields", []))

    for model, model_admin in model_admins.items():
        if isinstance(model_admin, AdminMixin):
            all_admin_fields[model].update(model_admin._ddb_annotations())

    # we always have id and never pk
    for fields in all_admin_fields.values():
        fields.add("id")
        fields.discard("pk")
        fields.discard("__str__")

    # throw away the hidden ones
    for model, fields in hidden_fields.items():
        for f in fields:
            all_admin_fields[model].discard(f)

    return model_admins, all_admin_fields
Esempio n. 56
0
 def get_related_field(self):
     return _get_foreign_key(
         parent_model=self.parent_backend.model,
         model=self.backend.model)
Esempio n. 57
0
# -*- coding: utf-8 -*-
Esempio n. 58
0
def _get_all_admin_fields(request):
    assert hasattr(request, "data_browser"), request

    def from_fieldsets(admin, include_calculated):
        auth_user_compat = settings.DATA_BROWSER_AUTH_USER_COMPAT
        if auth_user_compat and isinstance(admin, UserAdmin):
            obj = admin.model()  # get the change fieldsets, not the add ones
        else:
            obj = None

        fields = admin.get_fieldsets(request, obj)
        for f in flatten_fieldsets(fields):
            # skip calculated fields unless include_calculated given
            if include_calculated or _model_has_field(admin.model, f):
                yield f

    def visible(model_admin, request):
        has_attrs = all(
            hasattr(model_admin, a)
            for a in ["get_fieldsets", "model", "get_queryset"])
        if not has_attrs or not issubclass(model_admin.model, models.Model):
            debug_log(
                f"{type(model_admin)} instance does not look like a ModelAdmin or"
                " InlineModelAdmin")
            return False

        if _get_option(model_admin, "ignore", request):
            return False

        return model_admin.has_view_permission(request)

    all_model_fields = defaultdict(set)
    hidden_model_fields = defaultdict(set)

    def get_common(admin, model):
        all_model_fields[model].update(
            from_fieldsets(admin, include_calculated=False))
        all_model_fields[model].update(
            _get_option(admin, "extra_fields", request))
        hidden_model_fields[model].update(
            _get_option(admin, "hide_fields", request))

    model_admins = {}
    for model, model_admin in site._registry.items():
        if visible(model_admin, request):
            model_admins[model] = model_admin
            all_model_fields[model].update(
                model_admin.get_list_display(request))
            all_model_fields[model].add(open_in_admin)
            get_common(model_admin, model)

            # check the inlines, these are already filtered for access
            for inline in model_admin.get_inline_instances(request):
                if visible(inline, request):
                    try:
                        fk_field = _get_foreign_key(model, inline.model,
                                                    inline.fk_name)
                    except Exception as e:
                        debug_log(
                            e)  # ignore things like GenericInlineModelAdmin
                    else:
                        if inline.model not in model_admins:  # pragma: no branch
                            model_admins[inline.model] = inline
                        all_model_fields[inline.model].add(fk_field.name)
                        get_common(inline, inline.model)

    for model, model_admin in model_admins.items():
        # add in the backside of related fields's
        for field_name in set(
                all_model_fields[model]):  # copy because we might modify
            if _model_has_field(model, field_name):
                field = model._meta.get_field(field_name)
                if (field.is_relation
                        and field.related_model in all_model_fields
                        and not field.remote_field.hidden):
                    all_model_fields[field.related_model].add(
                        field.remote_field.name)

        # and the calculated fields
        all_model_fields[model].update(
            from_fieldsets(model_admin, include_calculated=True))

        # and any annotations that weren't mentioned in field_sets etc
        if isinstance(model_admin, AdminMixin):
            all_model_fields[model].update(model_admin._ddb_annotations())

    # we always have the actual pk field and never have the "pk" proxy
    for model, fields in all_model_fields.items():
        fields.add(model._meta.pk.name)
        fields.discard("pk")
        fields.discard("__str__")

    # throw away the hidden ones
    for model, fields in hidden_model_fields.items():
        for f in fields:
            all_model_fields[model].discard(f)

    return model_admins, all_model_fields