Как исправить URL, который не всегда перенаправляется без косой черты в Django

#python #html #django

#python #HTML #django

Вопрос:

Я разрабатываю веб-приложение на Python с помощью Django, и мои URL-адреса не всегда загружают правильное представление, если косая черта в конце не добавлена. Страница about отлично загружается с косой чертой и без нее, но моя страница контактов работает только в том случае, если добавлена косая черта в конце. Это также влияет на некоторые другие страницы. В конечном итоге он переходит к моей функции single_slug, которая является последним шаблоном в urls.py . Это должно быть сделано, если в URL-адресе нет совпадения, но косая черта в конце каким-то образом препятствует совпадению. В конечном итоге возвращается HttpResponse(f»{single_slug} ничему не соответствует!»).

Я попытался добавить APPEND_SLASH = True в свои настройки.py тем не менее, это ничего не изменило, поскольку по умолчанию это уже верно.

Вот мой views.py:

 from django.http import HttpResponse
from .models import Move, Artist
from django.contrib.auth.forms import UserCreationForm, AuthenticationForm
from django.contrib.auth import login, logout, authenticate
from django.shortcuts import render, redirect
from django.contrib import messages
from .forms import NewUserForm, ContactForm


# Create your views here.
def homepage(request):
    return render(request, 'main/home.html'

def about(request):
    return render(request, 'main/about.html')

def contact(request):
    form_class = ContactForm

    return render(request, 'main/contact.html', {
        'form': form_class,
    })

def single_slug(request, single_slug):
    artists = [a.artist_slug for a in Artist.objects.all()]
    if single_slug in artists:        
        artists = Artist.objects.filter(artist_slug__icontains=single_slug)
        return render(request, 'main/artist_detail.html', {'artists': artists})


    moves = [m.move_slug for m in Move.objects.all()]
    if single_slug in moves:
        moves = Move.objects.filter(move_slug__icontains=single_slug)
        return render(request, 'main/move_detail.html', {'moves': moves})

    return HttpResponse(f"{single_slug} does not correspond to anything!")

  

Вот мой models.py:

 class Move(models.Model):
        move_title = models.CharField(max_length=200)
        move_slug = models.SlugField(unique=True, max_length=250)

        def __str__(self):
            return self.move_title

        def save(self, *args, **kwargs):
            self.move_slug = slugify(self.move_title)
            super(Move, self).save(*args, **kwargs)

class Artist(models.Model):
        artist_name = models.CharField(max_length=200)
        artist_slug = models.SlugField(unique=True, max_length=250)

        def __str__(self):
            return self.artist_name

        def save(self, *args, **kwargs):
            self.artist_slug = slugify(self.artist_name)
            super(Artist, self).save(*args, **kwargs)

  

Вот мой urls.py:

 from django.urls import path
from django.conf.urls import url
from . import views



app_name = 'main'  # here for namespacing of urls.

urlpatterns = [

    path('', views.homepage, name="homepage"),
    path('about/', views.about, name="about"),
    path('contact/', views.contact, name="contact"),
    path('<single_slug>', views.single_slug, name="single_slug"),


]
  

Вот мой about.html:

 {% extends 'main/header.html' %}

{% block content %}

{% endblock %}
  

Вот мой contact.html:

 {% extends 'main/header.html' %}

{% block content %}
<h1>Contact</h1>
<form role="form" action="" method="post">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit">Submit</button>
</form>
{% endblock %}
  

Комментарии:

1. привет, можете ли вы добавить какой-либо конкретный пример, который должен соответствовать чему-то еще выше single_slug ? Спасибо.

2. Обратите внимание, что это if single_slug in artists: будет только True , если совпадает точный фрагмент, тогда как artist_slug__icontains будет True , если фрагмент содержится в artist_slug и не чувствителен к регистру. Возможно, было бы лучше удалить первый if оператор, а затем проверить if artists: после этого.

3. Почему это было бы лучше, поскольку я динамически генерирую имя slug с помощью функции сохранения? На всякий случай, если я случайно изменю регистр или что-то еще?

4. На данный момент вы дважды выбираете исполнителей ( artists = [a.artist_slug for a in Artist.objects.all()] и затем artists = Artist.objects.filter(...) ). Но если вы измените это на artists = Artists.objects.filter(...) затем проверьте if artists: , тогда вы будете извлекать исполнителей только дважды, что более эффективно. Однако, если вы внесете это изменение, поведение страницы немного изменится. Например. /eaTles/ начнет сопоставлять slug beatles , потому что icontains поведение отличается от текущей проверки if single_slug in artists: .

5. Общий подход к представлению одного объекта заключается в том, чтобы сделать что-то вроде artist = get_object_or_404(Artist, slug=single_slug) вместо artist = Artist.objects.filter(...) (что может соответствовать нескольким исполнителям). Смотрите этот пример в руководстве.

Ответ №1:

Django пытается сопоставить все шаблоны URL-адресов, прежде чем добавлять косую черту, поэтому single_slug шаблон предотвратит это, так как about и contact выглядят как слизни. /about и /contact должны обрабатываться одинаково для опубликованного вами кода, поэтому я не могу объяснить, почему вы видите разное поведение для них.

Если вы добавляете косую черту в свой single_slug путь, то /about и /contact следует перенаправить, чтобы добавить косую черту и соответствовать правильному шаблону.

 path('<single_slug>/', views.single_slug, name="single_slug")