Django添加表单用Widget Tweaks报AttributeError:'str'无'field'属性
问题分析与修复
核心错误原因
你的addCategory视图函数中,创建了context字典但未传递给render函数,导致模板无法获取正确的CategoryForm实例。如果基础模板v_base.html中恰好存在名为form的字符串变量,模板就会遍历该字符串的每个字符,而字符是str对象,没有field属性,从而触发AttributeError: 'str' object has no attribute 'field'。
另外,模板中使用了{{vendor.vendor_name}},但视图未将vendor变量传入context,也会导致该变量无法正常渲染。
修复步骤及代码调整
1. 修正视图函数的render调用,补充context参数
修改views.py中的addCategory函数,确保传递context,同时补充vendor变量,优化错误消息处理,并添加登录和角色校验:
from django.http.response import HttpResponse from django.shortcuts import render, redirect, get_object_or_404 from django.contrib import messages from django.contrib.auth.decorators import login_required, user_passes_test from django.template.defaultfilters import slugify from .models import Vendor from .forms import VendorForm from accounts.forms import UserProfileForm from accounts.models import UserProfile from accounts.views import check_role_vendor from menu.models import Category, Product from menu.forms import CategoryForm def get_vendor(request): vendor = Vendor.objects.get(user=request.user) return vendor @login_required(login_url='login') @user_passes_test(check_role_vendor) def addCategory(request): vendor = get_vendor(request) if request.method == 'POST': form = CategoryForm(request.POST) if form.is_valid(): category_name = form.cleaned_data['category_name'] category = form.save(commit=False) category.vendor = vendor category.slug = slugify(category_name) category.save() # 直接保存修改后的实例,而非form.save() messages.success(request, 'Category added successfully.') return redirect('menuBuilder') else: # 将表单错误转换为友好的字符串格式 error_msg = '; '.join([f"{field}: {', '.join(errors)}" for field, errors in form.errors.items()]) messages.error(request, error_msg) else: form = CategoryForm() context = { 'form': form, 'vendor': vendor } # 此处必须传入context参数 return render(request, 'vendor/addCategory.html', context)
2. 修正Category模型的缩进问题
你的models.py中Category类的代码缩进错误,修正后确保字段和方法属于类:
from django.db import models from vendor.models import Vendor class Category(models.Model): vendor = models.ForeignKey(Vendor, on_delete=models.CASCADE) category_name = models.CharField(max_length=50, unique=True) slug = models.SlugField(max_length=100, unique=True) description = models.TextField(max_length=250, blank=True) created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) class Meta: verbose_name = 'category' verbose_name_plural = 'categories' def clean(self): self.category_name = self.category_name.capitalize() def __str__(self): return self.category_name
为什么编辑表单正常?
编辑表单对应的视图函数中,你正确传递了包含form和vendor的context,模板能获取到合法的表单实例,因此不会出现遍历字符串的错误。
内容的提问来源于stack exchange,提问作者Rico
相关产品推荐
相关产品推荐

