(Django) Функция Delete не удаляет данные из базы данных
В настоящее время у меня есть таблица, в которой отображается список лекарств. В этой таблице в каждой строке данных есть кнопка удаления. Когда я нажимаю на нее, строка не удаляется.
Я попробовал тот же синтаксис удаления (в функции под названием 'destroy') в Django shell и это сработало. Я просто не понимаю, почему, когда я нажал на кнопку Remove внутри шаблона, ничего не произошло, даже после обновления.
drugs/views.py
from django.shortcuts import render, redirect
from django.views.generic import ListView
from .models import (
Drug,
)
from .forms import (
DrugForm,
)
def add_drug(request):
forms = DrugForm()
if request.method == 'POST':
forms = DrugForm(request.POST)
if forms.is_valid():
drug_id = forms.cleaned_data['drug_id']
name = forms.cleaned_data['name']
drug_type = forms.cleaned_data['drug_type']
Drug.objects.create(drug_id=drug_id, name=name,
drug_type=drug_type)
return redirect('drug-list')
context = {
'form': forms
}
return render(request, 'drugs/add_drug.html', context)
def destroy(request, drug_id):
d = Drug.objects.get(drug_id=drug_id)
d.delete()
d.save()
return redirect("/")
class DrugListView(ListView):
model = Drug
template_name = 'drugs/drug_list.html'
context_object_name = 'drug'
ddms/urls.py
from django.contrib import admin
from django.urls import path, include
# local
from .views import base, dashboard
from drugs.views import destroy
urlpatterns = [
path('admin/', admin.site.urls),
path('', dashboard, name='dashboard'),
path('drugs/', include('drugs.urls')),
path('delete/<int:drug_id>', destroy),
]
templates/drugs/drug_list.html
<div class="card-body--">
<div class="table-stats order-table ov-h">
<table id="bootstrapdatatable" class="table">
<thead>
<tr>
{% comment %} <th class="serial">#</th> {% endcomment %}
<th>ID</th>
<th>Name</th>
<th>Type</th>
<th>ACTION</th>
</tr>
</thead>
<tbody>
{% if drug %}
{% for drug in drug %}
<tr>
{% comment %} <td class="serial">{{ forloop.counter }}</td> {% endcomment %}
<td>{{ drug.drug_id }}</td>
<td>{{ drug.name }}</td>
<td>{{ drug.drug_type }}</td>
<td>
<div class="btn-group">
<button class="btn btn-link text-dark m-1 p-0" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<span class="">
<span id="action-button" class="fas fa-ellipsis-h icon-dark"></span>
</span>
</button>
<div class="dropdown-menu">
<a class="dropdown-item" href="#"><span class="fas fa-edit mr-2"></span>Edit</a>
<a class="dropdown-item text-danger" href="/delete/{{ drug.drug_id }}" data-title="Delete" data-toggle="modal" data-target="#delete"><span class="fas fa-trash-alt mr-2"></span>Remove</a>
</div>
</div>
</td>
</tr>
{% endfor %}
{% else %}
<tr><td>No Drug Data</td></tr>
{% endif %}
</tbody>
</table>
</div>
</div>
drugs/models.py
from django.db import models
from .drug_types import drug_types_list
class Drug(models.Model):
drug_id = models.CharField(max_length=20)
name = models.CharField(max_length=50, unique=True)
drug_type = models.CharField(max_length=20, choices=drug_types_list, default='pills')
def __str__(self):
return self.name
Мое предположение: если функция в views.py не виновата, то проблема может быть внутри моего шаблона, в кнопке Remove?
<td>
<div class="btn-group">
<button class="btn btn-link text-dark m-1 p-0" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<span class="">
<span id="action-button" class="fas fa-ellipsis-h icon-dark"></span>
</span>
</button>
<div class="dropdown-menu">
<a class="dropdown-item" href="#"><span class="fas fa-edit mr-2"></span>Edit</a>
<a class="dropdown-item text-danger" href="/delete/{{ drug.drug_id }}" data-title="Delete" data-toggle="modal" data-target="#delete"><span class="fas fa-trash-alt mr-2"></span>Remove</a>
</div>
</div>
</td>
Я только что начал строить проект на Django и из всех CRUD шаблонов этот мне кажется наиболее упрощенным. До этого я пробовал модуль DeleteView, object.save() после удаления, проверку моего html, ... к сожалению, никаких сообщений об ошибках не выскакивало.
Вы можете показать мне способ решения этой проблемы?
Вы не должны сохранять препарат, поскольку тогда вы снова создаете новую запись с теми же элементами:
def destroy(request, drug_id):
d = Drug.objects.get(drug_id=drug_id)
d.delete()
# no d.save()
return redirect('/')
Кроме того, вы должны создавать, обновлять и удалять сущности с помощью POST-запроса, а не GET-запроса: GET-запросы должны быть безопасными.
Вы можете ограничить доступ к представлению с помощью @require_POST
[Django-doc]:
from django.shortcuts import get_object_or_404
from django.views.decorators.http import require_POST
@require_POST
def destroy(request, drug_id):
d = get_object_or_404(Drug, drug_id=drug_id)
d.delete()
return redirect('/')
и использовать мини-форму на HTML-странице вместо ссылки:
<form method="POST" action="/delete/{{ drug.drug_id }}/">
<button type="submit" class="dropdown-item text-danger"><span class="fas fa-trash-alt mr-2"></span>Remove</button>
</form>
Не сохраняйте данные после удаления объекта, потому что если вы сохраните эти данные, они будут создаст те же данные в новом 'id'. Попробуйте это, Это сработает...
def destroy(request, drug_id):
d = Drug.objects.get(drug_id=drug_id)
d.delete()
return redirect("/")
Совместив с первым ответом от @Willem Van Onsem, я изменил путь к urls.py для уничтожения функции следующим образом:
path('delete/<str:drug_id>/', destroy)
с заменой int на string и включением слеша / в конце url