First off, I am using Django 3.2.9. Here are my models, pretty straightforward:
class AChallenge(models.Model):
name = models.CharField(max_length=255, unique=True)
class SubAdvanced(models.Model):
name: str = models.CharField(max_length=255, unique=True)
challenges = models.ManyToManyField(
AChallenge, related_name = 'challenge', through='SubAdvancedChallenge')
class SubAdvancedChallenge(models.Model):
sub_advanced = models.ForeignKey(
SubAdvanced, on_delete=models.CASCADE)
challenge = models.ForeignKey(
AChallenge, on_delete=models.CASCADE)
percentage = models.FloatField(
validators=[MinValueValidator(0), MaxValueValidator(1)])
Here is my admin :
class AChallengeAdmin(MyAppAdmin):
pass
admin.site.register(AChallenge, AChallengeAdmin)
class SubAdvancedChallengeInline(admin.TabularInline):
model = SubAdvancedChallenge
extra = 1
class SubAdvancedAdmin(MyAppAdmin):
inlines = (SubAdvancedChallengeInline,)
admin.site.register(SubAdvanced, SubAdvancedAdmin)
Despite all this, I am only getting this:
If I try to force the inclusion of the "challenges" field, like this:
class SubAdvancedAdmin(BelleEmpreinteAdmin):
fields = ("name", "challenges")
inlines = (SubAdvancedChallengeInline,)
I will get the following error:
(admin.E013) The value of 'fields' cannot include the ManyToManyField 'challenges', because that field manually specifies a relationship model.
The fact that my TabularInline
simply does not appear definitely seems like a bug, but it seems too crazy that this slipped through the cracks for so long. Anybody else met this issue?
CodePudding user response:
I am not sure, but what if you write it
@admin.register(SubAdvanced)
class SubAdvancedAdmin(BelleEmpreinteAdmin):
inlines = (SubAdvancedChallengeInline,)
CodePudding user response:
So as some may have guessed, and as I realized while re-reading my question, the issue was with permissions, since I am browsing my admin site as a non-superuser.
My modelAdmins are inherited from an override, that adds users with is_staff
set to True
into superadmin permissions, like this:
from django.contrib import admin
class MyAppAdmin(admin.ModelAdmin):
def _allow(self, user):
return user.is_staff or user.is_superuser
def has_change_permission(self, request, obj=None):
return self._allow(request.user)
def has_delete_permission(self, request, obj=None):
return self._allow(request.user)
def has_add_permission(self, request):
return self._allow(request.user)
def has_view_permission(self, request, obj=None):
return self._allow(request.user)
def has_module_permission(self, request):
return self._allow(request.user)
But I did not create such permissions for TabularInline
! So doing this did the trick:
class MyAppTabularInlineAdmin(admin.TabularInline):
def _allow(self, user):
return user.is_staff or user.is_superuser
def has_change_permission(self, request, obj=None):
return self._allow(request.user)
def has_delete_permission(self, request, obj=None):
return self._allow(request.user)
def has_add_permission(self, request, obj=None):
return self._allow(request.user)
def has_view_permission(self, request, obj=None):
return self._allow(request.user)
def has_module_permission(self, request):
return self._allow(request.user)
I then use this as my TabularInline
and voila:
class SubAdvancedChallengeInline(MyAppTabularInlineAdmin):
model = SubAdvancedChallenge
extra = 1