TabularInline для сквозной модели не отображается на Django 3
Прежде всего, я использую Django 3.2.9. Вот мои модели, довольно простые:
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)])
Вот мой админ :
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)
Согласно каждому учебнику, который я вижу в интернете, я должен получить хороший встроенный редактор вроде этого:
Несмотря на все это, я получаю только следующее:
Если я попытаюсь принудительно включить поле "challenges", например, так:
class SubAdvancedAdmin(BelleEmpreinteAdmin):
fields = ("name", "challenges")
inlines = (SubAdvancedChallengeInline,)
Я получу следующую ошибку:
(admin.E013) The value of 'fields' cannot include the ManyToManyField 'challenges', because that field manually specifies a relationship model.
Тот факт, что мой TabularInline
просто не появляется, определенно похож на ошибку, но кажется слишком сумасшедшим, что это так долго ускользало от внимания. Кто-нибудь еще сталкивался с этой проблемой?
Я не уверен, но что если вы напишете это
@admin.register(SubAdvanced)
class SubAdvancedAdmin(BelleEmpreinteAdmin):
inlines = (SubAdvancedChallengeInline,)
Итак, как некоторые могли догадаться, и как я понял, перечитав свой вопрос, проблема была в правах доступа, поскольку я просматриваю свой администраторский сайт как не-суперпользователь.
Мои modelAdmins наследуются от переопределения, которое добавляет пользователей с is_staff
установленными в True
правами суперадмина, вот так:
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)
Но я не создавал таких разрешений для TabularInline
! Так что это помогло:
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)
Затем я использую это в качестве TabularInline
и вуаля:
class SubAdvancedChallengeInline(MyAppTabularInlineAdmin):
model = SubAdvancedChallenge
extra = 1