NoReverseMatch в / - не понимая причины
Я пытаюсь создать выпадающий элемент 'edit settings/ view profile page' в моей navbar. Функциональность работала до вызова из выпадающего элемента, который теперь выдает ошибку NoReverseMatch, как показано ниже:
Повтор для 'show_profile_page' с аргументами '('',)' не найден. Проверен 1 шаблон(ы): ['subs/(?P[0-9]+)/profile/\Z']
Я пытаюсь понять, почему возникает эта ошибка, когда я вызываю этот url в других шаблонах без проблем, но теперь, когда я попытался поместить это в выпадающий список, я получаю это. Должен ли я делать обратный вызов в views.py? Буду признателен за любые подсказки...
**urls.py ** (subs app)
from django.urls import path
from .views import UserRegisterView, UserEditView, PasswordsChangeView, ShowProfilePageView, EditProfilePageView
#from django.contrib.auth import views as auth_views
from . import views
urlpatterns = [
path('register/', UserRegisterView.as_view(), name='register'),
path('edit_profile/', UserEditView.as_view(), name='edit_profile'),
#path('password/', auth_views.PasswordChangeView.as_view(template_name='registration/change-password.html')),
path('password/', PasswordsChangeView.as_view(template_name='registration/change-password.html')),
path('password_success', views.password_success, name="password_success"),
path('<int:pk>/profile/', ShowProfilePageView.as_view(), name="show_profile_page"),
path('<int:pk>/edit_profile_page/', EditProfilePageView.as_view(), name="edit_profile_page")
]
views.py (subs app)
from django.shortcuts import render, get_object_or_404
from django.views import generic
from django.views.generic import DetailView
from django.contrib.auth.forms import UserCreationForm, UserChangeForm, PasswordChangeForm
from django.urls import reverse_lazy
from .forms import SignUpForms, EditProfileForm, PasswordUpdateForm
from django.contrib.auth.views import PasswordChangeView
from nooz2.models import Profile
# Create your views here.
class UserRegisterView(generic.CreateView):
form_class = SignUpForms
template_name = 'registration/register.html'
success_url = reverse_lazy('login')
class UserEditView(generic.UpdateView):
form_class = EditProfileForm
template_name = 'registration/edit_profile.html'
success_url = reverse_lazy('home')
def get_object(self):
return self.request.user
class PasswordsChangeView(PasswordChangeView):
form_class = PasswordUpdateForm
#form_class = PasswordChangeForm
success_url = reverse_lazy('password_success')
def password_success(request):
return render(request, 'registration/password_success.html', {})
class ShowProfilePageView(DetailView):
model = Profile
template_name = 'registration/user_profile.html'
def get_context_data(self, *args, **kwargs):
#users = Profile.objects.all()
context = super(ShowProfilePageView, self).get_context_data(*args, **kwargs)
page_user = get_object_or_404(Profile, id=self.kwargs['pk'])
context["page_user"] = page_user
return context
class EditProfilePageView(generic.UpdateView):
model = Profile
template_name = 'registration/edit_profile_page.html'
fields = ['bio', 'profile_pic', 'site_url', 'facebook_url', 'instagram_url']
success_url = reverse_lazy('home')
navbar.html
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<div class="container-fluid">
<a class="navbar-brand" href="{% url 'home' %}">Nooz</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNavDropdown" aria-controls="navbarNavDropdown" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNavDropdown">
<ul class="navbar-nav">
<!-- Dropdown code for categories -->
{% if category_menu %}
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
Categories
</a>
<ul class="dropdown-menu">
<!-- generates list of categories -->
{% for item in category_menu %}
<li><a class="dropdown-item" href="{% url 'category' item|slugify|title %}">{{ item }}</a></li>
{% endfor %}
</ul>
</li>
{% endif %}
{% if user.is_authenticated %}
<li class="nav-item">
<a class="nav-link" href="{% url 'new_post' %}">Add Post</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{% url 'add_category' %}">Add Category</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
Profile
</a>
<ul class="dropdown-menu dropdown-menu-dark">
<li><a class="nav-link dropdown-item" href="{% url 'edit_profile' %}">Settings</a></li>
<li><a class="nav-link dropdown-item" href="{% url 'show_profile_page' user.profile.id %}">View Profile Page</a></li>
<li><a class="nav-link dropdown-item" href="{% url 'edit_profile_page' user.profile.id %}">Edit Profile Page</a></li>
<li><a class="nav-link dropdown-item" href="{% url 'logout' %}">Logout</a></li>
</ul>
</li>
{% else %}
<li class="nav-item">
<a class="nav-link" href="{% url 'register' %}">Register</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{% url 'login' %}">Login</a>
</li>
{% endif %}
</ul>
</div>
</div>
</nav>
Я попробовал следующее:
- проверено на опечатки
- изменил urls.py, добавив '/' в качестве суффикса
- удалил user.profile.id, чтобы проверить, не выдает ли он ошибку
Без forms.py
я не могу привести пример кода, но я подозреваю, что если вы создадите объект Profile
в вашей панели администратора, это решит проблему. Если вы не уверены, как зарегистрировать модель Profile
в панели администратора, то простой пример можно найти в документации здесь:
https://docs.djangoproject.com/en/4.1/ref/contrib/admin/#modeladmin-objects
Простое создание отношения OneToOne не создает объект автоматически, и вам все равно нужно автоматически создать объект Profile
в фоновом режиме. Или, если есть информация, которую пользователь должен предоставить, чтобы иметь Profile
, то пользователь проходит через соответствующий путь пользователя, чтобы убедиться, что он создал объект, прежде чем ему будет представлена страница с url, обратным к странице его профиля (используя профиль, которого нет)
Вы можете проверить это, добавив отладочный verbose в шаблон
<h1>{{ user.profile.id|default:"Does not exist" }}</h1>
Где-нибудь в подходящем месте, и я полагаю, что это будет None
, а также закомментировать обратные url к профилю пользователя.
В шаблоне происходит то, что поскольку объект профиля не существует, django изящно игнорирует ошибку , которая обычно выдается как ошибка DoesNotExist
, если бы вы попытались получить доступ к этому объекту в оболочке или, например, в коде представления.