Django- Шаблон не найден

Я не могу заставить работать функции удаления, редактирования и добавления отзывов. Ошибки появляются, как только я пытаюсь перейти по установленным ссылкам. Когда я пытаюсь добавить новый отзыв, используя мою ссылку на странице отзывов, я получаю следующее сообщение:

TemplateDoesNotExist в /reviews/add

Я не понимаю почему, потому что я связал url выше с шаблоном, который я создал.

Проблема с моими просмотрами редактирования/удаления заключается в том, что при нажатии на кнопку он ищет url просто /edit/ или /delete/, а не reviews/edit/int:pk или reviews/delete/int:pk согласно моим urls.

Я вставил свой код ниже, любая помощь будет очень признательна! У меня такое чувство, что я буду пинать себя, когда пойму!

reviews.html:

{% extends "base.html" %}
{% load static %}

{% block content %}
<div class="container-fluid home-container">
    <div class="row align-items-center">
        <div class="col-sm-12 text-center mt-4">
            <h2><strong>Reviews</strong></h2>
        </div>
    </div>
    {% for review in reviews %}
    <hr class="hr-1">
    <div class="row featurette">
        <div class="col-sm-12">
            <h2 class="featurette-heading">{{ review.title }}</h2>
            <p class="lead">{{ review.content }}</p>
            <div class="row justify-content-between mx-1">
                <p>By: {{ review.user }}</p>
                <p>Created on: {{ review.created }}</p>
                <p>Last Updated: {{ review.updated }}</p>
            </div>
            <!-- Add user authentication if -->
            <div class="text-center">
                <a href="edit/{{ review.id }}" class="mx-2">
                    <button class="positive-button mb-2">Edit</button></a>
                <a href="delete/{{ review.id }}" class="mx-2 mb-2">
                    <button class="negative-button">Delete</button></a>
            </div>
        </div>
    </div>
    {% endfor %}
    
    <div class="row">
        <div class="col-sm-12 text-center py-4">
            {% if user.is_authenticated %}
            <a href="{% url 'home:add_review' %}">
                <button class="positive-button-lg">Add a review</button>
            </a>
            {% else %}
            <p>If you would like to add your own review, please login or sign up if you haven't already!</p>
            {% endif %}
        </div>
    </div>
    
</div>
{% endblock %}

add_review.html:

{% extends "base.html" %}
{% load static %}

{% block content %}
<div class="container-fluid">
    <div class="row justify-content-center">
        <div class="col-auto text-center p-3">
            <form method="post" style="margin-top: 1.3em;">
                {{ review_form }}
                {% csrf_token %}
                <button type="submit" class="btn btn-primary btn-lg">Submit</button>
            </form>
        </div>
    </div>
{% endblock %}

views.py:

from django.shortcuts import render
from django.views import View
from django.urls import reverse_lazy
from django.views.generic import UpdateView, DeleteView
from .models import Reviews
from .forms import ReviewForm


def home(request):
    ''' Returns the home page.'''
    return render(request, 'home/index.html')


def reviews(request):
    ''' Returns the reviews page.'''

    serialized_reviews = []

    reviews = Reviews.objects.all()

    for review in reviews:
        serialized_reviews.append({
            "title": review.title,
            "content": review.content,
            "user": review.user,
            "created": review.created,
            "updated": review.updated,
        })

    context = {
        "reviews": serialized_reviews
        }
    print(serialized_reviews)
    return render(request, 'home/reviews.html', context)


class AddReview(View):
    '''View which allows the user to add a new review.'''

    def get(self, request, *args, **kwargs):

        review = Reviews
        review_form = ReviewForm
             
        context = {
            'review': review,
            'review_form': review_form,
            'user': review.user,
            'title': review.title,
            'content': review.content,
        }
        return render(request, 'add_review.html', context)
    
    def post(self, request, *args, **kwargs):

        review_form = ReviewForm(data=request.POST)

        if review_form.is_valid():
            obj = review_form.save(commit=False)
            obj.user = request.user
            obj.save()
            
        return redirect("home:reviews")


class DeleteReview(DeleteView):
    '''View which allows the user to delete the selected review.'''
    model = Reviews
    template_name = 'delete_review.html'
    success_url = reverse_lazy('reviews')


class EditReview(UpdateView):
    '''View which allows the user to edit the selected review.'''
    model = Reviews
    template_name = 'edit_review.html'
    fields = ['title', 'content']

urls.py:

from django.urls import path
from . import views


app_name = 'home'

urlpatterns = [
    path('', views.home, name='home'),
    path('reviews', views.reviews, name='reviews'),
    path('reviews/add', views.AddReview.as_view(), name='add_review'),
    path('reviews/delete/<int:pk>', views.DeleteReview.as_view(), name='delete_review'),
    path('reviews/edit/<int:pk>', views.EditReview.as_view(), name='edit_review'),
]

Мне кажется, вы неправильно вписываете урлы, например, вот так под div text-center:

<a href="edit/{{ review.id }}" class="mx-2">

Должно быть:

<a href="{% url 'yourappname:edit' review.id %}">

Основное отличие заключается в имени моего приложения, которое является 'core'. Также я забыл добавить поле content в модель, но это легко сделать, форма просто обработает его, как только вы выполните миграцию. (кроме list.html)

models.py

from django.db import models
from django.contrib.auth import get_user_model
from django.utils import timezone

class Reviews(models.Model):
    user = models.ForeignKey(get_user_model(), on_delete=models.CASCADE)
    title = models.CharField(max_length=128)
    created_at = models.DateTimeField(auto_now_add=timezone.now())
    updated_at = models.DateTimeField(auto_now=timezone.now())

forms.py

from django import forms
from core.models import Reviews

class ReviewsForm(forms.ModelForm):
    
    class Meta:
        model = Reviews
        fields = '__all__'

views.py

from core.models import Reviews
from core.forms import ReviewsForm
from django.shortcuts import render, redirect

def list_reviews(request):
    reviews = Reviews.objects.all()

    context = {
        "reviews": reviews
        }
    return render(request, 'reviews/list.html', context)

def add_review(request):    
    if request.method == 'POST':
        form = ReviewsForm(request.POST)

        if form.is_valid():
            form.save()
            return redirect('/reviews/')
    else:
        form = ReviewsForm()

    context = {
        'form': form
        }
    return render(request, 'reviews/detail.html', context)

def edit_review(request, pk):    
    if request.method == 'POST':
        form = ReviewsForm(request.POST)

        if form.is_valid():
            obj = Reviews.objects.get(id=pk)
            obj.title = form.cleaned_data['title']
            obj.user = form.cleaned_data['user']
            obj.save()
            return redirect('/reviews/')
    else:
        obj = Reviews.objects.get(id=pk)
        form = ReviewsForm(instance=obj)

    context = {
        'form': form
        }
    return render(request, 'reviews/detail.html', context)

def delete_review(request, pk):
    obj = Reviews.objects.get(id=pk)
    obj.delete()
    return redirect('/reviews/')

urls.py

from django.urls import path
import core.views as views

app_name = 'core'

urlpatterns = [
    path('reviews/', views.list_reviews, name='list-reviews'),
    path('reviews/add', views.add_review, name='add-review'),
    path('reviews/edit/<int:pk>/', views.edit_review, name='edit-review'),
    path('reviews/delete/<int:pk>/', views.delete_review, name='delete-review'),
]

list.html

{% extends "base.html" %}
{% load static %}

{% block content %}
<div class="container-fluid home-container">
    <div class="row align-items-center">
        <div class="col-sm-12 text-center mt-4">
            <h2><strong>Reviews</strong></h2>
        </div>
    </div>
    {% for review in reviews %}
    <hr class="hr-1">
    <div class="row featurette">
        <div class="col-sm-12">
            <h2 class="featurette-heading">{{ review.title }}</h2>
            <p class="lead">{{ review.content }}</p>
            <div class="row justify-content-between mx-1">
                <p>By: {{ review.user }}</p>
                <p>Created on: {{ review.created_at }}</p>
                <p>Last Updated: {{ review.updated_at }}</p>
            </div>
            <!-- Add user authentication if -->
            <div class="text-center">
                <a href="{% url 'core:edit-review' pk=review.id %}" class="mx-2">
                    <button class="positive-button mb-2">Edit</button></a>
                <a href="{% url 'core:delete-review' pk=review.id %}"  class="mx-2 mb-2">
                    <button class="negative-button">Delete</button></a>
            </div>
        </div>
    </div>
    {% endfor %}
    
    <div class="row">
        <div class="col-sm-12 text-center py-4">
            {% if user.is_authenticated %}
            <a href="{% url 'core:add-review' %}">
                <button class="positive-button-lg">Add a review</button>
            </a>
            {% else %}
            <p>If you would like to add your own review, please login or sign up if you haven't already!</p>
            {% endif %}
        </div>
    </div>
    
</div>
{% endblock %}

detail.html

{% extends "base.html" %}
{% load static %}

{% block content %}
<div class="container-fluid">
    <div class="row justify-content-center">
        <div class="col-auto text-center p-3">
            <form method="post" style="margin-top: 1.3em;"> 
                {% csrf_token %}
                <table>                    
                    {{ form }}
                </table>
                <button type="submit" class="btn btn-primary btn-lg">Save</button>
            </form>
        </div>
    </div>
{% endblock %}

Согласно вашим урлам, это review/edit/<int:pk>. Поэтому вы должны добавить то же самое в тег href.

Изменить это:

<a href="edit/{{ review.id }}"

К этому:

<a href="review/edit/{{ review.id }}"

Поэтому вы получаете эту ошибку

Я исправил это, во-первых, путь в моем представлении add_review был неправильным, который я исправил и теперь он работает (спасибо Ивану).

Я также не указывал ID в представлении 'reviews', поэтому при переходе по ссылкам на кнопки редактирования и обзора, он не знал, что я имел в виду под 'id', поскольку я не указал, что это такое в контексте представления

Спасибо всем за помощь!

Вернуться на верх