Opened 2 years ago

Closed 22 months ago

Last modified 14 months ago

#20807 closed Bug (fixed)

Inline don't care about max_num if has_add_permission is set to false

Reported by: yves.guimard@… Owned by: polmuz
Component: contrib.admin Version: 1.6
Severity: Normal Keywords: admin inline max_num
Cc: polmuz Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Hi,

I have defined an Inline to display a large number of objects (more than max_num default value).
So, I set max_num to 10000 and it works well until I set has_add_permission to false

Here is the class defined in a admin.py file:

class softInline(admin.TabularInline):

model = software
max_num = 10000
extra = 0
readonly_fields = ('name', 'version', 'uninstall', 'manualy_created',)
def has_add_permission(self, request):

return False

Did I missed something or do you think that it's a bug?

Thanks,
Yves

Attachments (1)

djbug-20807.zip (18.1 KB) - added by polmuz 22 months ago.
Small django project that reproduces the bug

Download all attachments as: .zip

Change History (8)

comment:1 Changed 2 years ago by timo

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset

The code in contrib.admin sets max_num to zero if has_add_permission isn't True.

https://github.com/django/django/commit/b1b1da1e#L0R363

Could you describe your use case a little more and what the actual problem is?

comment:2 Changed 2 years ago by yves.guimard@…

hello, the actual problem is that I can't save from admin view an object (machine) which have more than 1000 foreign objects displayed with an inline.
It throw an index error (django/forms/formsets.py in full_clean) because max_num is set by default to 1000

So I have set max_num = 10000 and it works well until I set has_add_permission to false. If I remove has_add_permission, max_num takes my value (10000). If I set again has_add_permission to false, max_num value takes 1000 (default value) and not 10000.

Here is a simplified example of my models.py file:


class machine(models.Model):

name = models.CharField(max_length=100, verbose_name = _('machine|name'))
vendor = models.CharField(max_length=100,null=True, blank=True, default='undefined',verbose_name = _('machine|vendor'))
product = models.CharField(max_length=100,null=True, blank=True, default='undefined',verbose_name = _('machine|product'))

class software(models.Model):

name = models.CharField(max_length=100, verbose_name = _('software|name'))
version = models.CharField(max_length=500,null=True, blank=True, default='undefined', verbose_name = _('software|version'))
uninstall = models.CharField(max_length=500,null=True, blank=True, default='undefined', verbose_name = _('software|uninstall'))
host = models.ForeignKey(machine, verbose_name = _('software|host'))


And of the admin.py file:


class ueAdmin(admin.ModelAdmin):

list_max_show_all = 600
list_per_page = 100
actions_selection_counter = True
list_select_related = True

class softInline(admin.TabularInline):

model = software
max_num = 10000
extra = 0
readonly_fields = ('name', 'version', 'uninstall',)
def has_add_permission(self, request):

return False

class machineAdmin(ueAdmin):

select_related = True
fields = ['name', 'vendor','product']
list_display = ('lastsave','name','vendor','product')
list_filter = (('lastsave',)
search_fields = ('name', 'vendor','product')
inlines = [osInline, netInline, softInline]
filter_horizontal = ('packages',)
date_hierarchy = 'lastsave'
ordering =('-lastsave',)

admin.site.register(machine, machineAdmin)


Real files of this project are here (dev branch):https://github.com/updatengine/updatengine-server/tree/dev_v2/inventory

It's really weired and that's why I thought it is was a bug. Tell me if you need more information, I would be happy to contribute a little!

comment:3 Changed 22 months ago by polmuz

  • Owner changed from nobody to polmuz
  • Status changed from new to assigned

comment:4 Changed 22 months ago by polmuz

  • Cc polmuz added
  • Component changed from Uncategorized to contrib.admin
  • Triage Stage changed from Unreviewed to Accepted

I'm attaching a small django project with a sqlite3 db included where you can reproduce this bug.

Expected behavior with has_add_permission set to False for the inline:

  • Go to an admin page with more than 1000 inline forms for a given related object
  • Edit some inline objects (without adding one, you don't have permissions to do that)
  • Save and continue being happy

Current behavior:

  • Go to an admin page with more than 1000 inline forms for a given related object
  • What? I thought that this object had more than 1000 inline items, whatever... (only 1000 are displayed even if max_num for that inline admin is larger)
  • Edit some inline object
  • Try to save, index error :(

If you change has_add_permissions to True, all the inline items are displayed and you can edit and save without any problem.

Changed 22 months ago by polmuz

Small django project that reproduces the bug

comment:5 Changed 22 months ago by polmuz

  • Resolution set to fixed
  • Status changed from assigned to closed

This is fixed in master so it'll be available in 1.6 release.

comment:6 Changed 22 months ago by yves.guimard@…

Great, thanks for the fix!

comment:7 Changed 14 months ago by yves.guimard@…

  • Version changed from 1.5 to 1.6

Hi,

It seems that the bug is still here but produce a different error:

Now, when I try to save a form with a lot of inline an exception is raised with this message:
Please submit 0 or fewer forms.

If I understand Django code max_num is in this context set to 0. But max_num is set in my class to 10000:

class softInline(admin.TabularInline):
    model = software
    max_num = 100000
    extra = 0
    readonly_fields = ('name', 'version', 'uninstall', 'manualy_created',)

Could you look at this error?
Thanks
Yves

Note: See TracTickets for help on using tickets.
Back to Top