#python #django #debugging #django-rules
#python #django #отладка #django-rules
Вопрос:
Я новичок в Django. Я пытался настроить django-rules с пользовательской моделью пользователя, но продолжаю получать 404 при попытке доступа к странице. Вот как выглядит настройка:
Пользовательская модель пользователя
class User(AbstractBaseUser, PermissionsMixin):
class Meta:
verbose_name = _('user')
verbose_name_plural = _('users')
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False, unique=True)
first_name = models.CharField(max_length=200)
last_name = models.CharField(max_length=200)
email = models.EmailField(
verbose_name='email address',
max_length=255,
unique=True,
)
is_active = models.BooleanField(default=False)
objects = UserManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = []
def __str__(self):
return self.email
settings.py
AUTHENTICATION_BACKENDS = (
'rules.permissions.ObjectPermissionBackend',
'django.contrib.auth.backends.ModelBackend',
)
установленные приложения
INSTALLED_APPS = [
# ...
'rules.apps.AutodiscoverRulesConfig',
]
rules.py
@rules.predicate
def is_organisation_member(user, organisation):
"""Check if user is an active organisation member"""
m = get_if_exists(
OrganisationMember,
user=user,
organisation=organisation,
organisation__state=Organisation.LifecycleState.ACTIVE
)
if not m:
return False
if not m.is_active:
return False
return True
rules.add_perm('organisations.member', (is_authenticated amp; is_active amp; is_organisation_member))
views.py
def get_organisation_by_slug(request, *args, **kwargs):
return get_object_or_404(Organisation, workspace_name=kwargs['workspace'])
@permission_required('organisations.member', fn=get_organisation_by_slug)
def OrganisationView(request, workspace):
# ...
urls.py
urlpatterns = [
path('admin/', admin.site.urls),
# ...
# organisation
path('<str:workspace>', v.OrganisationView, name="organisation-show"),
# ...
]
Согласно отладке, is_organisation_member
возвращает True, но пользователь по-прежнему получает ошибку 404 при попытке просмотреть страницу (без декоратора django-rules permission_required
страница работает). Есть идеи, почему я получаю ответ 404?
Комментарии:
1. Не могли бы вы показать нам полную ошибку, поскольку вы обычно получаете эту ошибку, если ваш urls.py это неправильно или если вы ПОЛУЧАЕТЕ вместо POST или что-то в этом роде?
2. Конечно:
Page not found (404) Request Method: GET Request URL: http://127.0.0.1:8000/abc1 Raised by: bb.views.OrganisationView Not found You're seeing this error because you have DEBUG = True in your Django settings file. Change that to False, and Django will display a standard 404 page.
URL: 127.0.0.1:8000/abc1 . abc1 — это имя организации, и оно находится в базе данных. URL работает, когда я удаляю декоратор.3. не могли бы вы добавить свой urls.py
4. Конечно, готово. Спасибо!
5. @AyanSh спасибо за рассмотрение вопроса, когда вы спросили о urls.py Я начал задаваться вопросом, была ли проблема на самом деле в другом месте, и начал настраивать код в разных местах.
Ответ №1:
без
permission_required
декоратора django-rules страница работает
Это было правдой только наполовину! Это сработало, когда генератор был удален и присутствовали существующие тестовые данные. Но когда запрос ничего не вернул, появилась ошибка 404.
Я неправильно предположил, что проблема заключалась в настройке правил, но после удаления декоратора ошибка все еще сохранялась. Раньше я не видел эту ошибку, потому что у меня всегда были автоматически сгенерированные тестовые данные (список проектов), но не в этот раз. Итак, после просмотра функции просмотра я понял, что вызывал ошибку 404, когда запрос проекта возвращал пустой список:
@permission_required('organisations.member', fn=get_organisation_by_slug)
def OrganisationView(request, workspace):
# Query strings:
# Extract 'tab' value appended to url as
# ?tab=projects
tab = request.GET.get('tab', '')
# Get organisation
try:
o = Organisation.objects.get(workspace_name=workspace)
except Organisation.DoesNotExist:
raise Http404("Not found.")
if tab == 'projects':
# Get project list
try:
p = Project.objects.filter(organisation__workspace_name=workspace)
.order_by('-created_at')
except Project.DoesNotExist:
raise Http404("Not found")
else:
raise Http404("Not found...") # ERROR CAUSED BY THIS LINE
# To fix the error, I have removed the above line and added the below query
# p = Project.objects.filter(organisation__workspace_name=workspace)
# .order_by('-created_at')
# Set context
context = {
'o': o,
'projects': p
}
return render(request, 'bb/home.html', context)
Поскольку я был уверен, что с моим представлением все в порядке, я не опубликовал полную функцию, из-за чего кому-либо еще было трудно исправить ошибку. Я понял, что ошибка была в представлении после добавления has_perm(self, perm, obj=None): return True
в пользовательскую модель, но все еще получаю ошибку 404.