You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 08:55:00