Почему bootstrap может загрузить фон для одного модала, но не для другого
Итак, вот моя проблема: я создаю проект django, основанный на учебниках и т.д., и я нашел, что модалы для обратной связи с пользователем - это хорошая идея. Я не хотел создавать много различных частей кода для модалов, поэтому я решил выбрать общий модал, который я могу использовать для всех моих случаев.
<div class="modal fade" id="{{ modal_id }}" tabindex="-1" role="dialog" aria-labelledby="{{ modal_id }}Label" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="{{ modal_id }}Label">{{ title }}</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<!-- Dynamic message -->
<p id="modalMessage">{{ message }}</p>
<!-- Conditional content based on context_type -->
{% if context_type == "account_deletion" %}
<form method="POST" action="{{ action_url }}">
{% csrf_token %}
<div class="form-group">
<label for="password" style="margin-bottom:1rem;">Enter Your Password to Confirm:</label>
<input type="password" id="password" name="password" class="form-control" required style="margin-bottom: 1rem;">
</div>
<button type="submit" class="btn btn-danger">Delete Account</button>
</form>
{% elif context_type == "item_deletion" %}
<p>Are you sure you want to delete this item?</p>
{% endif %}
</div>
<div class="modal-footer">
{% if context_type == "item_deletion" %}
<form method="POST" action="{{ action_url }}">
{% csrf_token %}
<button type="submit" class="btn {{ submit_class }}">{{ submit_label }}</button>
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
</form>
{% endif %}
</div>
</div>
</div>
</div>
В этом проекте будет только два случая, либо пользователь хочет сделать что-то серьезное, например, удалить аккаунт, тогда ему нужно будет ввести свой пароль для подтверждения.
или просто подтвердить удаление рекомендации или комментария и т.д.
Вот здесь и кроется проблема. По какой-то причине модальное окно отлично работает, когда я хочу удалить учетную запись, но если я хочу удалить рекомендацию из профиля пользователя, оно не открывает модальное окно и выбрасывает на экран эту ошибку:
[![введите описание изображения здесь][1]][1]
Я решил, что дело в модальном форматировании, но это не так, поскольку снова все работает нормально при удалении учетной записи, и после этого я предположил, что это может быть способ доступа к ней, но снова не уверен. Я также попробовал переместить модальное включение в нижнюю часть цикла и за пределы цикла полностью.
Единственное, что я могу предположить, это то, что он либо пытается загрузить несуществующую рекомендацию, либо я неправильно настроил кнопку? Но я не знаю.
Вот дополнительный код для справки.
{% extends "base.html" %}
{% load static %}
{% block content %}
<h2>{{ profile.user.username }}'s Profile</h2>
<p>Bio: {{ profile.bio }}</p>
<p>Location: {{ profile.location }}</p>
{% if profile.avatar %}
<img src="{{ profile.avatar.url }}"
alt="{{ profile.user.username }}'s avatar"
class="profile-avatar">
{% else %}
<img src="{% static 'images/default_avatar.png' %}"
alt="Default avatar"
class="profile-avatar">
{% endif %}
{% if user.is_authenticated %}
{% if user == profile.user %}
<!-- Show the edit profile button only if the logged-in user is the profile owner -->
<a href="{% url 'edit_profile' username=request.user.username %}"
class="btn btn-primary">
Edit Profile
</a>
<a href="{% url 'delete_account' username=request.user.username %}" class="btn btn-danger" data-bs-toggle="modal" data-bs-target="#deleteAccountModal">
Delete Account
</a>
{% endif %}
{% endif %}
<!-- Display Recommendations -->
<h3>Recommendations</h3>
{% for recommendation in recommendations %}
<div class="recommendation">
<p>{{ recommendation.content }}</p>
{% if user == profile.user %}
<a href="{% url 'edit_recommendation' recommendation_id=recommendation.id %}" class="btn btn-primary">Edit</a>
<button type="button" class="btn btn-danger" data-bs-toggle="modal" data-bs-target="#deleteRecommendationModal{{ recommendation.id }}">
Delete
</button>
<!-- Delete Recommendation Confirmation Modal -->
{% include "modal/modal.html" with modal_id="deleteRecommendationModal"|add:recommendation.id title="Confirm Recommendation Deletion" message="Are you sure you want to delete this recommendation?" context_type="item_deletion" action_url=recommendation.delete_url submit_class="btn-danger" submit_label="Delete Recommendation" %}
{% endif %}
</div>
{% endfor %}
<!-- Account Deletion Confirmation Modal -->
{% include "modal/modal.html" with modal_id="deleteAccountModal" title="Confirm Account Deletion" message="This action is irreversible. Please confirm." context_type="account_deletion" action_url=delete_account_url submit_class="btn-danger" submit_label="Delete Account" %}
{% endblock %}
(код моего профиля.html)
def profile(request, username):
"""
Profile view to display user profile along with their recommendations.
Args:
request (HttpRequest): The request object to handle the request.
username (str): The username of the user whose profile is being viewed.
Returns:
HttpResponse: Renders the profile page with the user's profile and recommendations.
"""
user = get_object_or_404(User.objects.select_related('profile'), username=username)
recommendations = Recommendation.objects.filter(user=user)
delete_account_url = reverse("delete_account", kwargs={"username": username})
return render(request, "profiles/profile.html", {
"profile": user.profile,
"recommendations": recommendations,
"can_edit": request.user == user,
"delete_account_url": delete_account_url,
})
(просмотр моего профиля)
def delete_recommendation(request, recommendation_id):
"""
Handles the deletion of an existing recommendation.
Args:
request: The HTTP request object containing user data.
recommendation_id (int): The ID of the recommendation to be deleted.
Returns:
Redirects to the user's profile page after the recommendation is deleted.
Description:
This view allows the logged-in user to delete their own recommendation.
If the user is not the owner of the recommendation, they are redirected
to their profile page.
"""
recommendation = get_object_or_404(models.Recommendation, id=recommendation_id)
#defensive programming stop user from navigating via url to delete others recommendation
if recommendation.user != request.user:
return render(request, "error/403.html", status=403)
recommendation.delete()
messages.success(request, "Recommendation deleted successfully!")
return redirect('profile', username=request.user.username)
удалите просмотр рекомендаций
class Recommendation(models.Model):
"""Recommendation model
Args:
models (django model class): class from djangos model framework
Description:
recommendation model for the database, once created here get's migrated
to the database and is used for allowing users to see active recommendations
made
"""
def __str__(self):
"""String func
Returns:
formatted string for admin viewing
"""
return f"{self.title} | Recommended by {self.user}"
#title of the recommendation
title = models.CharField(max_length=100, unique=True)
# user, our fk linking back to the user who created it
user = models.ForeignKey(
User,
on_delete=models.CASCADE,
related_name="recommendations",
)
# optional description field for the recommendation
description = models.TextField(max_length=200, blank=True, null=True)
# we add lat/long cords for rec to put on map (invisible to user)
latitude = models.FloatField(blank=True, null=True)
longitude = models.FloatField(blank=True, null=True)
# address of place in question
address = models.CharField(max_length=255, unique=True)
# Many-to-many field for categories
categories = models.ManyToManyField(
Category,
related_name="recommendations",
blank=True,
)
def average_score(self):
"""
Average Score Func
Args:
self: (num): number to average
Description:
Method to calculate the votes, the votes are added by users and calculated here
when the object (recommendation) is displayed, the vote is tallied and then shown
"""
votes = self.votes.all()
if votes.count() == 0:
# No votes, return 0 as default
return 0
total_score = sum(vote.vote for vote in votes)
# Return the average score, rounded to 1 decimal place
return round(total_score / votes.count(), 1)
def delete_url(self):
return reverse("delete_recommendation", args=[self.id])
urlpatterns = [
path("recommendations/", recommendations, name="recommendations"),
path("add_recommendation/", add_recommendation, name="add_recommendation"),
path("edit_recommendation/<int:recommendation_id>/", edit_recommendation, name="edit_recommendation"),
path("delete_recommendation/<int:recommendation_id>/", delete_recommendation, name="delete_recommendation"),
]
наконец, рекомендательная модель (потому что в учебнике мне пришлось добавить обратную ссылку) и рекомендательные представления
любая помощь будет оценена по достоинству [1]: https://i.sstatic.net/pT9bLGfg.png
РЕДАКТИРОВАТЬ 1:
Быстрая правка я сломал эту кнопку в profile.html
From:
<button type="button" class="btn btn-danger" data-bs-toggle="modal" data-bs-target="#deleteRecommendationModal{{ recommendation.id }}">
Delete
</button>
<!-- Delete Recommendation Confirmation Modal -->
To:
<button type="button" class="btn btn-danger" data-bs-toggle="modal" data-bs-target="#deleteRecommendationModal{{ recommendation.id }}">
<!-- Delete Recommendation Confirmation Modal -->
Кнопка все еще не работает, но она показывает модальный текст (и кнопки) и удаляет, когда она работает, так что я думаю, что ошибка здесь