Django模块、应用和导入问题 - 对象没有'form'属性

0 投票
3 回答
2650 浏览
提问于 2025-04-16 16:00

我有一个注册表单,需要在我网站的每个页面上加载,如果用户是访客的话。我觉得最简单的方法就是创建一个“注册”应用/模块,并在init.py里定义表单变量,这样在每次视图加载时就会自动初始化,只要我导入了这个模块。不过,我在让视图找到这个表单变量时遇到了一些麻烦,出现了“全局名称 'form' 未定义”的错误。下面是我的设置:

我有一个 /signup/init.py 和一个 /signup/form.py 文件。

这是我的 init.py:

from django import forms
from signup.form import SignUpForm

form = SignupForm()

这是我的 form.py:

class SignupForm(forms.Form):
    fullname = forms.CharField(min_length=3, max_length=25, initial='name', error_messages={'required': 'A unique username is required.', 'min_length': 'Your username must contain at least 3 characters.'})
    username = forms.CharField(min_length=3, max_length=25, initial='choose a username', error_messages={'required': 'A unique username is required.', 'min_length': 'Your username must contain at least 3 characters.'})
    password = forms.CharField(min_length=7, initial='choose a password', error_messages={'required': 'Please enter a password.','min_length': 'Your password must contain at least 7 characters.'})
    email = forms.EmailField(initial='e-mail address', error_messages={'required': 'Please enter a valid email address.', 'invalid': 'Please enter a valid email address.'})
    find_me = forms.BooleanField(initial=True, required=False)
    tos = forms.BooleanField(error_messages={'required': 'You must accept our Terms of Service.'})

我试图从我的 /views/index.py 文件中加载这些内容:

from django.http import HttpResponse
from pymongo import *
from user import *
import mongo
from django.shortcuts import render_to_response
from django.template import RequestContext, loader
import signup

#index view
def index(request):

    return render_to_response('index.html',
        {'form': signup.form},
        context_instance=RequestContext(request),
    ) 

我在 index.py 中去掉了不相关的代码……但基本上……(我可能会在返回语句中加个 if else,只在用户未注册时返回 'form':form)

我这样做完全错了吗?有人能告诉我我哪里做错了吗?

::编辑::

另外,我注意到我在返回时没有包含 signup.form,但这仍然会抛出一个错误。

AttributeError at /
'module' object has no attribute 'form'

我已经修改了上面的代码以适应这个问题。

3 个回答

1

你应该使用 from signup import form 或者 from signup import * 这样可以让 form 这个变量在你的 views.py 文件中可用。如果你用 import signup,那样会把整个模块导入进来,并且会用 signup 这个名字来引用它,这样你就需要用 signup.form 来访问 form 了。

1

我不太明白你把它赋值给一个标识符的目的是什么?

我会这样做:

#init.py:
from django import forms
from signup.form import SignUpForm

#index view
def index(request):

    return render_to_response('index.html',
        {'form': signup.SignUpForm()},
        context_instance=RequestContext(request),
    ) 

或者

#init.py:
from django import forms
from signup.form import SignUpForm as Form

#index view
def index(request):

    return render_to_response('index.html',
        {'form': signup.Form()},
        context_instance=RequestContext(request),
    ) 

更新

把你的 form.py 改成:

class SignUpForm(forms.Form):

而不是:

class SignupForm(forms.Form):
2

我想提醒你,你现在的做法其实是个非常糟糕的主意。你在每次请求中都使用同一个表单实例,这样做是很危险的,可能会导致信息在请求之间泄露。最好不要这样做。

相反,你可以使用Django自带的机制来帮你处理这个问题:上下文处理器。在你的signup/form.py文件中,定义一个简单的函数:

def signup_form(request):
    return SignupForm()

然后把这个添加到settings.py中的TEMPLATE_CONTEXT_PROCESSORS里:

'signup.form.signup_form',

撰写回答