Django创建Menu时出现“Restaurant匹配查询不存在”错误求助
解决Django CreateView传递多URL参数及Restaurant匹配错误的问题
我来帮你一步步搞定这个问题,你遇到的核心问题有两个:模板跳转链接生成不完整,以及MenuCreateView没有正确从URL参数中获取并关联Restaurant对象。
1. 修复模板中的跳转链接
你当前模板里的<a href="createMenu">Make a Menu</a>是相对路径,这会导致生成的URL缺失pk和name这两个必要参数,最终触发"Restaurant matching query does not exist"错误。
把Menus.html里的按钮链接改成Django的{% url %}模板标签,明确传递两个参数:
<div class="col-md-2"> <button><a href="{% url 'createMenu' pk=user.pk name=rest.name %}">Make a Menu</a></button> </div>
这个标签会根据你在urls.py里定义的createMenu路由规则,自动生成完整的URL(比如/profile/1/restaurant/MyCafe/createMenu/),确保所有必要参数都被包含。
2. 修正MenuCreateView的逻辑
你的MenuCreateView里的form_valid方法错误地尝试从self.request.restaurant获取餐厅对象,但这个属性根本不存在。我们需要从URL的kwargs中提取name参数,查询对应的Restaurant,同时还要验证该餐厅属于当前登录用户,避免越权操作。
修改views.py中的MenuCreateView:
class MenuCreateView(LoginRequiredMixin, CreateView): template_name = 'restaurants/makeMenu.html' form_class = MenuCreateForm def form_valid(self, form): # 从URL参数中获取餐厅名称 rest_name = self.kwargs.get('name') # 查询当前用户名下的对应餐厅 try: restaurant = Restaurant.objects.get(name=rest_name, account=self.request.user) except Restaurant.DoesNotExist: raise PermissionDenied() # 如果餐厅不存在或不属于当前用户,拒绝访问 form.instance.restaurant = restaurant return super().form_valid(form)
这里做了两个关键改进:
- 从
self.kwargs中获取URL里的name参数(Django会自动将URL中的参数解析到视图的kwargs字典中) - 加上了用户权限验证,确保当前登录用户是该餐厅的所有者,防止恶意用户访问他人的餐厅菜单创建页面
3. 额外优化建议(可选)
- 建议用餐厅的
pk代替name作为URL参数,因为餐厅名称可能重复或包含特殊字符,会导致URL解析问题。如果要改的话,只需要把urls.py里的<str:name>改成<int:rest_pk>,然后在视图中用Restaurant.objects.get(pk=rest_pk, account=self.request.user)查询即可。 - 可以在MenuCreateView中重写
get_context_data方法,把当前餐厅信息传递到模板,让创建菜单的页面显示对应的餐厅名称,提升用户体验:
def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) rest_name = self.kwargs.get('name') context['restaurant'] = Restaurant.objects.get(name=rest_name, account=self.request.user) return context
这样修改后,你点击"Make a Menu"按钮就能正确跳转到创建页面,提交表单时也能正确关联到对应的餐厅,不会再出现"Restaurant matching query does not exist"的错误了。
内容的提问来源于stack exchange,提问作者bruzza42
相关产品推荐
相关产品推荐

