Django: в представлениях как сделать редирект, если параметр (связанный с шаблоном url) не соответствует результату модели?
Я извиняюсь, я все еще изучаю django и просто бьюсь головой о стену с некоторыми из них. Текущая проблема в том, что у меня есть представление, связанное через параметр URL, и оно работает для показа информации о моей модели, но если вы жестко вводите url в другой параметр, он показывает страницу. Я пытался перенаправить его, но это не работает, я чувствую, что это может быть из-за того, как и где я возвращаю свой рендеринг. Посоветуйте, как настроить url на основе модели и, если информация о модели не существует, либо через 404, либо перенаправить на другую страницу?
Вид:
@login_required(login_url='login_register')
def project_page(request, name):
project = Project.objects.all()
issueticket1 = Issue.objects.filter(related_project__name__exact=name)
table = IssueTable(issueticket1)
project_list = {}
for p in project:
if p.name == name:
project_list = {'id': p.project_id, 'startdate': p.start_date,
'enddate': p.end_date, 'description': p.description}
return render(request, 'main_projects.html', {'name': name, 'project_list': project_list, 'project': project, 'table': table})
URL CONFIG:
path('projects/<str:name>/', views.project_page, name="project_page"),
Не знаю, какова ваша точная цель, она не очень ясна для меня, поэтому я предполагаю. здесь. Но лучшее, что можно сделать, когда объект не существует при получении объекта, это вернуть сообщение об ошибке 404 not found.
Итак, в вашем коде вы в основном получаете все проекты и используете операторы if, чтобы проверить, совпадают ли они по названию. Что может быть довольно дорого для базы данных, и кроме того, циклическое прохождение по всем проектам не рекомендуется, представьте, что у вас 1000 проектов в базе данных, это означает, что вы проходите по каждому из них и проверяете, совпадает ли название, что не позволит странице быстро загрузиться.
Вместо этого вы можете использовать метод filter и получить все проекты, соответствующие названию.
from django.shortcuts import get_object_or_404, redirect
from django.core.exceptions import ValidationError
@login_required(login_url='login_register')
def project_page(request, name):
project_list = Project.objects.all()
issueticket1 = Issue.objects.filter(related_project__name__exact=name)
table = IssueTable(issueticket1)
# Instead of looping get the projects get the matching item, you can use get_object_or_404 from django
project = get_object_or_404(Project, name=name)
# or an alternative
try:
project = project_list.get(name=name)
except Project.DoesNotExist:
raise ValidationError("project does not exist")
# If you really need to redirect you can
return redirect("/your-url/")
return render(request, 'main_projects.html', {'name': name, 'project_list': project_list, 'project': project, 'table': table})
Вы можете просто добавить оператор if внутри вашего шаблона
{% if issueticket1 %}
~Do the Normal things~
{% else %}
No Match Was Found
{% end if %}
Вы также можете сделать 404, как сказал @kwamito, это всегда хорошо.
Или вы можете просто добавить if в представлении и пользовательское перенаправление, например:
- Я не уверен на 100% в том, как это должно работать, поэтому просто брошу сюда два потенциальных редиректа
@login_required(login_url='login_register')
def project_page(request, name):
projectMatches = Project.objects.filter(name=name)
if not projectMatches.count():
# No Projects
redirect('errorpage')
# Note: .first() - it will be the Object or None
issueticket1 = Issue.objects.filter(related_project__name__exact=name).first()
if not issueticket1:
# No Tickets
redirect('errorpage')
table = IssueTable(issueticket1)
project_list = {}
for p in projectMatches:
project_list = {'id': p.project_id, 'startdate': p.start_date,
'enddate': p.end_date, 'description': p.description}
return render(request, 'main_projects.html', {'name': name, 'project_list': project_list, 'project': project, 'table': table})
В любом случае вам, вероятно, следует использовать Project.objects.filter() вместо того, чтобы перебирать их все и вручную проверять имена (заставьте db делать это)