Python和Django网页应用按钮点击无效
**更新 我有一个网页应用程序,是由另一个人开发的,但他现在不愿意帮我解决bug。我有一些经验,但显然不够,无法解决这个问题。
在这个网页应用中,有一个按钮点击后没有任何反应。这个按钮应该是用来把用户信息保存到数据库里的。我不太明白这个点击事件是怎么和可能的 views.py
文件联系起来的。
在我的 templates/add-inventory.html
文件中,我看到了:
<a href="{% url 'crm:inventory' %}" class="btn btn-light rounded-pill me-1"> Cancel </a>
<button type="submit" class="btn btn-success rounded-pill"> Save </button>
保存按钮没有任何反应。
我在 views.py
文件中看到了:
@login_required(login_url='crm:login')
@permission_required("crm.add_inventory", raise_exception=True)
def addInventory(request):
form = InventoryForm()
staff = User.objects.all().order_by('first_name')
vendor_form = VendorForm()
if request.method == 'POST':
form = InventoryForm(request.POST)
if form.is_valid():
inventory_instance = form.save()
if not request.POST.get('vendor'):
vendor_form = VendorForm(request.POST)
if vendor_form.is_valid():
vendor = vendor_form.save(commit=False)
vendor.added_by = request.user
vendor.save()
inventory_instance.vendor = vendor
inventory_instance.save()
stocks = request.POST.getlist('stock')
for i in range(len(staff)):
if int(stocks[i]) > 0:
InventoryStock.objects.create(
inventory = inventory_instance,
user = staff[i],
stock = stocks[i]
)
messages.success(request, 'Item added successfully')
return redirect('crm:inventory')
这个按钮是怎么调用 views.py
中的代码的?任何帮助都非常感谢。
我把所有文件下载到本地,并使用VS Code进行调试,但没有任何进展。
我在 add-inventory.html
文件中添加了 name="addInventory"
,如下所示:
这并没有起作用。
<a href="{% url 'crm:inventory' %}" class="btn btn-light rounded-pill me-1"> Cancel </a>
<button type="submit" class="btn btn-success rounded-pill" name="AddInventory"> Save </button>
下面的代码是来自 urls.py
文件,按照要求提供。希望这是你需要的信息。
path('inventory', inventory, name='inventory'),
path('inventory/add', addInventory, name='add-inventory'),
path('inventory/update/<int:pk>', updateInventory, name='update-inventory'),
path('inventory/delete/<int:pk>', deleteInventory, name='delete-inventory')
我试着在代码中找到POST部分。我觉得这就是它(在 add-inventory.html 中找到的):
<div class="card bg-info-subtle shadow-none position-relative overflow-hidden mb-4">
<div class="card-body px-4 py-3">
<div class="row align-items-center">
<div class="col-9">
<h4 class="fw-semibold mb-8">Add Inventory</h4>
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item">
<a class="text-muted text-decoration-none" href="/">Home</a>
</li>
<li class="breadcrumb-item">
<a class="text-muted text-decoration-none" href="{% url 'crm:inventory' %}">Inventory</a>
</li>
<li class="breadcrumb-item" aria-current="page">Add Inventory</li>
</ol>
</nav>
</div>
</div>
</div>
</div>
<div class="widget-content searchable-container list">
<div class="p-3">
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
<div class="row">
<div class="col-md-4">
<div class="py-3">
<h4>Item Info</h4>
<p>The information about the item number, machine it belongs to, decription of the item and the prices.>
</div>
</div>
<div class="col-md-8">
<div class="card card-body">
{{form.name | as_crispy_field}}
{{form.item_number | as_crispy_field}}
{{form.machine | as_crispy_field}}
<div class="row">
<div class="col-md-6">
{% crispy_addon form.buying_price prepend="$" %}
</div>
<div class="col-md-6">
{% crispy_addon form.selling_price prepend="$" %}
</div>
</div>
{{form.taxable | as_crispy_field}}
{{form.description | as_crispy_field}}
</div>
</div>
<div class="col-md-4">
<div class="py-3">
<h4>Vendor Info</h4>
<p>You can select the vendor of the inventory item or you can add new vendor and it will be assocciated with the item.</p>
</div>
</div>
<div class="col-md-8">
<div class="card card-body">
<div class="row mb-2">
<div class="col-md-10">
<div id="vendor-field">
{{form.vendor | as_crispy_field}}
</div>
</div>
<div class="col-md-2">
<div class="d-grid">
<a type="button" id="toggle-button" class="btn btn-success" style="margin-top: 30px"><i class="fa fa-plus me-2"></i> Add</a>
</div>
</div>
</div>
<div id="add-vendor-content" style="display:none">
<div class="row">
<div class="col-md-3">
{{vendor_form.status|as_crispy_field}}
</div>
<div class="col-md-9">
{{vendor_form.name|as_crispy_field}}
</div>
<div class="col-md-6">
{{vendor_form.phone_number|as_crispy_field}}
</div>
<div class="col-md-6">
{{vendor_form.email|as_crispy_field}}
</div>
<div class="col-md-12">
{{vendor_form.address|as_crispy_field}}
</div>
</div>
<div class="card-header mb-2">
<h5 class="text-center">Contact Person</h5>
</div>
<div class="row">
<div class="col-md-6">
{{vendor_form.contact_person_name|as_crispy_field}}
</div>
<div class="col-md-6">
{{vendor_form.contact_person_phone_number|as_crispy_field}}
</div>
<div class="col-md-6">
{{vendor_form.contact_person_email|as_crispy_field}}
</div>
</div>
</div>
</div>
</div>
<div class="col-md-4">
<div class="py-3">
<h4>Stock Availability</h4>
<p>It will show how much stock every staff user have right now</p>
</div>
</div>
<div class="col-md-8">
<div class="card card-body">
{% for i in staff %}
<div class="row">
<div class="col-md-6">
<div class="mb-3">
<input type="text" name="staff_user" id="id_staff_user" class="form-control" value="{{i.get_full_name}}" readonly/>
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<input type="number" name="stock" id="id_stock" class="form-control" value="0"/>
</div>
</div>
</div>
{% endfor %}
</div>
</div>
<div class="col-md-4">
<div class="py-3">
<h4>Notes</h4>
<p>You can store the related notes to the instance here</p>
</div>
</div>
<div class="col-md-8">
<div class="card card-body">
{{form.notes|as_crispy_field}}
</div>
</div>
<div class="col-md-4"></div>
<div class="col-md-8">
<div class="card card-body">
<div class="text-end">
<a href="{% url 'crm:add-inventory' %}" class="btn btn-light rounded-pill me-1">Cancel</a>
<button type="submit" class="btn btn-success rounded-pill">Save</button>
我把下面这一行改成了 action="{% url 'crm:add-inventory' %}"
,但这也没有帮助。
<form method="POST" enctype="multipart/form-data" action="{% url 'crm:add-inventory' %}">
来自配置文件夹的 urls.py 文件:
from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('admin/', admin.site.urls),
path('ckeditor/', include('ckeditor_uploader.urls')),
path('', include(('crm.urls', 'crm'), namespace='crm')),
]
urlpatterns = urlpatterns + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
来自 crm 文件夹的 urls.py 文件:
from django.urls import path
from .views import *
from .models import *
app_name = "crm" #I added this, it was not originally here
urlpatterns = [
path('', login, name='login'),
path('logout', logout, name='logout'),
path('dashboard', dashboard, name='dashboard'),
path('dashboard/stats', dashboardStatistics, name='dashboard-statistics'),
path('dashboard/monthly-sale', monthlySaleChart, name='dashboard-monthly-sale'),
path('dashboard/revenue-update', revenueUpdateChart, name='dashboard-revenue-update'),
path('dashboard/tax-update', taxUpdateChart, name='dashboard-tax-update'),
path('dashboard/recent-sales-order', receentSalesOrders, name='dashboard-recent-sales-orders'),
path('dashboard/recent-invoices', receentInvoices, name='dashboard-recent-invoices'),
path('dashboard/recent-payments', receentPayments, name='dashboard-recent-payments'),
path('dashboard/recent-quotations', receentQuotations, name='dashboard-recent-quotations'),
path('profile', profile, name='profile'),
path('staff', users, name='staff-users'),
path('staff/add', addUser, name='add-staff-user'),
path('staff/update/<int:id>', updateUser, name='update-staff-user'),
path('staff/delete/<int:id>', deleteUser, name='delete-staff-user'),
path('roles', roles, name='roles'),
path('role/add', addRole, name='add-role'),
path('role/update/<int:id>', updateRole, name='update-role'),
path('role/delete/<int:id>', deleteRole, name='delete-role'),
path('companies', companies, name='companies'),
path('company/add', addCompany, name='add-company'),
path('company/update/<int:pk>', updateCompany, name='update-company'),
path('company/delete/<int:pk>', deleteCompany, name='delete-company'),
path('contacts', contacts, name='contacts'),
path('contact/add', addContact, name='add-contact'),
path('contact/update/<int:pk>', updateContact, name='update-contact'),
path('contact/delete/<int:pk>', deleteContact, name='delete-contact'),
path('machines', machines, name='machines'),
path('machine/add', addMachine, name='add-machine'),
path('machine/update/<int:pk>', updateMachine, name='update-machine'),
path('machine/delete/<int:pk>', deleteMachine, name='delete-machine'),
path('inventory', inventory, name='inventory'),
path('inventory/add', addInventory, name='add-inventory'),
path('inventory/update/<int:pk>', updateInventory, name='update-inventory'),
path('inventory/delete/<int:pk>', deleteInventory, name='delete-inventory'),
path('settings/invoice', invoiceSetting, name='invoice-setting'),
path('invoices', invoices, name='invoices'),
path('invoice/add', addInvoice, name='add-invoice'),
path('invoice/export/<str:inv_no>', exportInvoice, name='export-invoice'),
path('invoice/delete/<int:pk>', deleteInvoice, name='delete-invoice'),
path('credit-notes', creditnotes, name='credit-notes'),
path('delivery-order', deliveryOrders, name='delivery-orders'),
path('credit-note/export/<str:cn_number>', exportCreditNote, name='export-credit-note'),
path('credit-note/delete/<int:pk>', deleteCreditNote, name='delete-credit-note'),
path('settings/estimate', estimateSetting, name='estimate-setting'),
path('estimates', estimates, name='estimates'),
path('estimate/add', addEstimate, name='add-estimate'),
path('estimate/view/<str:est_no>', viewEstimate, name='view-estimate'),
path('estimate/update/<str:est_no>', updateEstimate, name='update-estimate'),
path('estimate/copy/<str:est_no>', copyEstimate, name='copy-estimate'),
path('estimate/convert/<str:est_no>', convertEstimate, name='convert-estimate'),
path('estimate/export/<str:est_no>', exportEstimate, name='export-estimate'),
path('estimate/delete/<int:pk>', deleteEstimate, name='delete-estimate'),
path('quotation/item/delete/<int:pk>', deleteEstimateItem, name='delete-estimate-item'),
# Payment Routes
path('settings/stripe-keys', stripeApiKeySetting, name='stripe-keys-setting'),
path('payment/make-payment/<str:uuid>', makePayment, name='make-payment'),
path('payment/charge', CreateCheckoutSession, name='charge'),
path('payment/success/<str:uuid>', successMsg, name='success'),
path('payment/error', errorMsg, name='cancel'),
path('payment/paid', alreadyPaid, name='already-paid'),
path('service-reports', saleOrders, name='sale-orders'),
path('service-report/add', addSaleOrder, name='add-sale-order'),
path('service-report/view/<str:so_number>', viewSaleOrder, name='view-sale-order'),
path('service-report/update/<str:so_number>', updateSaleOrder, name='update-sale-order'),
path('service-report/copy/<str:so_number>', copySaleOrder, name='copy-sale-order'),
path('service-report/export/<str:so_number>', exportSaleOrder, name='export-sale-order'),
path('service-report/delete/<int:pk>', deleteSaleOrder, name='delete-sale-order'),
path('sale-order/item/delete/<int:pk>', deleteSaleOrderItem, name='delete-sale-order-item'),
path('delivery-order/create/<str:invoice_number>', createDeliveryOrder, name='create-delivery-order'),
path('delivery-order/export/<str:do_number>', exportDeliveryOrder, name='export-delivery-order'),
path('payments', payments, name='payments'),
path('payments/update/<int:pk>', updatePayment, name='update-payment'),
path('payments/delete/<int:pk>', deletePayment, name='delete-payment'),
path('vendors', vendors, name='vendors'),
path('vendor/update/<int:id>', updateVendor, name='update-vendor'),
path('vendor/delete/<int:id>', deleteVendor, name='delete-vendor'),
path('reporting/soa', soa, name='soa'),
path('reporting/soa/export', exportsoa, name='export-soa'),
path('reporting/tax-report', taxReport, name='tax-report'),
path('reporting/tax-report/export', exportTaxReport, name='export-tax-report'),
path('reporting/machines-report', machinesReport, name='machines-report'),
path('reporting/debit-report', debitReport, name='debit-report'),
path('reporting/debit-report/export', exportDebitReport, name='export-debit-report'),
path('ajax/machines', clientMachinesFilterAjax, name='client-machines-filter-ajax'),
]
原开发者给我发了一些修改。Wimerge 显示他添加了一个新的视图,并更改了更新库存的文件,如下图所示: [Winmerge 视图1
2 个回答
假设你已经在你的 urls.py
文件中设置了 app_name = "crm"
,那么你只需要把按钮的链接改成 {% url 'crm:add-inventory' %}
,这个名字就是你在 urls.py
文件里定义的。
如果你已经把 VSCode 设置好,可以正常调试,那么你可以在 inventory
视图和 addInventory
视图里设置断点。你会发现你调用的是第一个,因为它的名字是 inventory。
更一般的解释
下面是 Django 的工作原理。
- 首先,用户点击一个
按钮/链接
- 这个
按钮或链接
会向特定的网址
发送信息请求 - 这个网址必须和 Django 的
urls.py
中的某个网址匹配 - 这个
网址
必须连接到views.py
中的一个视图
,这个视图是实际操作发生的地方
可能出现的问题
- 上面链接中的某个环节出现了问题。
或者
- Django 的视图/代码中出现了错误
回答:
根据提供的信息,我们只看到了第 1、3、4 步。
- 我们在问题中看不到
表单提交
的动作值
。
或者
- 我们看不到
javascript/jquery
代码用于自定义表单的提交/上传
。
这两者必须有一个。
所以,
检查表单提交的动作值,确保它和 Django 的 urls.py
中的某个网址匹配。它可能是下面的某个形式(任意一种都可以)。
- {% url 'add-inventory' %}
- {% url 'crm:addInventory' %}
- inventory/add
或者
在自定义表单提交的 js/jquery 代码中检查有效的网址。