Django模板表单Action传递Slug字段出现URL匹配错误求助
问题:Django表单提交时URL匹配错误及无响应问题
背景与需求
现有两个Django模型:Service(存储所有服务信息)和OrderService(存储用户下单记录)。需求是用户选择服务后,视图自动通过请求获取用户信息、通过Slug获取服务信息完成下单,但当前遇到两个问题:
- 表单无Action属性时提交无响应
- 给Action传递Slug时出现"URL匹配不存在"错误
相关代码
模型代码
Service模型
class Service(models.Model): title = models.CharField(max_length=50) slug = models.SlugField(unique=True, allow_unicode=True, default='-') current_queue = models.PositiveSmallIntegerField(null=True, blank=True, default=0) max_queue = models.PositiveSmallIntegerField(null=True, blank=True) def save(self, *args, **kwargs): self.slug = slugify(self.title) return super(Service, self).save(args, kwargs) def __str__(self) -> str: return f'{self.title} {self.current_queue}'
OrderService模型
from django.conf import settings User = settings.AUTH_USER_MODEL class OrderService(models.Model): user = models.ForeignKey(User, on_delete=models.CASCADE) service = models.ForeignKey(Service, on_delete=models.CASCADE) description = models.TextField(null=True, blank=True) def __str__(self) -> str: return f"{self.user} {self.service}"
订单表单代码
from django import forms from .models import OrderService class UserOrder(forms.ModelForm): class Meta: model = OrderService fields = ['description']
视图代码
@login_required(login_url='LOGIN') def order_for_service(request, slug): if request.method == "POST": form = UserOrder(request.POST) if form.is_valid(): object = form.save(commit=False) object.user = request.user object.service = Service.objects.get(slug=slug) service = Service.objects.get(slug=slug) service.current_queue += 1 object.save() service.save() return redirect("HOME") else: form = UserOrder() context = {'form': form} return render(request, "order.html", context=context)
模板代码
{% extends 'root.html' %} {% block documents %} <div class="container-fluid"> <div class="row"> <div class="col"> <form action="{% url 'ORDERING' slug %}" method="post"> {{form.as_p}} {% csrf_token %} <input type="submit" value="submit" name="submit"> </form> </div> </div> </div> {% endblock documents %}
URL配置
urlpatterns = [ path('<str:slug>/', order_for_service, name='ORDERING'), ]
问题分析与解决办法
核心问题
模板中使用{% url 'ORDERING' slug %}时,上下文未传递slug变量,导致Django无法生成正确URL,抛出匹配错误;而表单无Action时,若当前URL的slug参数未正确传递,也会导致提交无响应。
修复步骤
传递slug到模板上下文
修改视图代码,将slug加入context,让模板能获取到该变量:context = {'form': form, 'slug': slug} return render(request, "order.html", context=context)优化表单Action(推荐)
表单可省略Action属性,默认提交到当前请求的URL,无需手动传递slug,避免URL生成错误:<form method="post"> {{form.as_p}} {% csrf_token %} <input type="submit" value="submit" name="submit"> </form>优化视图数据库查询
视图中重复查询Service对象,可合并为一次查询提升性能:@login_required(login_url='LOGIN') def order_for_service(request, slug): service = Service.objects.get(slug=slug) if request.method == "POST": form = UserOrder(request.POST) if form.is_valid(): object = form.save(commit=False) object.user = request.user object.service = service service.current_queue += 1 object.save() service.save() return redirect("HOME") else: form = UserOrder() context = {'form': form, 'slug': slug} return render(request, "order.html", context=context)添加异常处理(可选)
使用get_object_or_404替代get,避免slug不存在时抛出异常,返回404页面:from django.shortcuts import get_object_or_404 @login_required(login_url='LOGIN') def order_for_service(request, slug): service = get_object_or_404(Service, slug=slug) # 后续代码不变
内容的提问来源于stack exchange,提问作者Mehdi
相关产品推荐
相关产品推荐

