5

在这里,一个 Django 初学者在表单工作时遇到了很多麻烦。是的,我已经完成了教程并浏览了很多网络 - 我所拥有的是我在这里和其他网站上找到的东西。我正在使用 Python 2.7 和 Django 1.5。(虽然官方文档很广泛,但它倾向于假设您已经了解其中的大部分内容——不适合作为初学者参考,甚至不适合作为高级教程)

我正在尝试为“扩展”用户详细信息创建一个表单 - 例如。公司名称、街道地址等,但表格数据未保存到数据库中。

最初我试图创建一个扩展标准User模型的模型,但我放弃了——需要修改太多,而且在这个阶段它已经进入了超出我能力范围的细节。因此,我创建了一个新模型,名为UserProfile

class UserProfile(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL, unique=True) 
    company = models.CharField(max_length=50, blank=True)
    address1 = models.CharField(max_length=50, blank=True)
    address2 = models.CharField(max_length=50, blank=True)
    city = models.CharField(max_length=20, blank=True)
    region = models.CharField(max_length=20, blank=True)
    postcode = models.CharField(max_length=10, blank=True)
    country = models.CharField(max_length=20, blank=True)
    phone = models.CharField(max_length=30, blank = True)

我在网上看到了不同的参考资料,关于我应该使用ForeignKey(如上所述)还是使用 OneToOne 链接到用户模型。

我正在尝试使用 ModelForm (对于应该是简单的表单保持简单)。这是我的forms.py

from django.forms import ModelForm
from .models import UserProfile   

class UserDetailsForm(ModelForm):
    class Meta:
        model = UserProfile
        fields = ['company','address1','address2','city','region', 'postcode','country','phone']

这是我的看法:

def UserDetailsView(request):
    #f = 0
    if request.method == 'POST':
        f = UserDetailsForm(request.POST, instance = request.user)
        if f.is_valid():
            f.save()
    else:
        f = UserDetailsForm(request.POST , instance = request.user)

    print "UserDetails objects: ", (UserProfile.objects.all()) 

    return render_to_response('plagweb/console/profile.html', 
                              { 'form': f}, 
                              context_instance=RequestContext(request))     

(是的,UserProfile 与 UserDetail 存在不一致 - 这是我所有黑客行为的产物,一旦我开始工作就会修复)

诊断显示f.is_valid()返回 True。同样,诊断显示UserProfile.objects.all()为空。我在 save() 之后的上面的视图中尝试了这个,也在 Django 控制台上尝试了这个。

这是我的模板:

 <form method="POST" action="">
 <table>{{ form }}</table>
 <input type="submit" value="Update" />
 {% csrf_token %}
 </form>

目前的主要问题是表单数据没有保存到数据库中。我不知道是否正在读取(一旦我在数据库中有一些数据......)

一种想法是这种User关系可能会导致问题?


附录,遵循 Daniel Roseman 的有用评论/帮助:

现在表单正在正确保存(通过诊断和命令行检查确认。但是,当我返回表单时,它不显示现有数据。显示一个带有空数据字段的表单。据我所知,我m 正确传递实例数据。

是否有需要更改的 ModelForm 设置?

这是修改后的视图:

def UserDetailsView(request):
    #print "request co:", request.user.profile.company
    f = UserDetailsForm(request.POST, instance = request.user.profile )

    if request.method == 'POST':
        if f.is_valid():
            profile = f.save(commit=False)
            profile.user = request.user
            profile.save()

    return render_to_response('plagweb/console/profile.html', 
                              { 'form': f}, 
                              context_instance=RequestContext(request))     

诊断显示request.user.profile设置正确(特别是公司字段)。但是,表单显示为空字段。HTML 源代码也不显示任何数据值。作为额外检查,我还尝试了一些模板诊断:

<table border='1'>
    {% for field in form%}
        <tr>
            <td>{{field.label}}</td>
            <td>{{field.value}}</td>
        </tr>
    {% endfor%}
</table>

这会正确列出字段标签,但值都报告为None.

为了完整起见,现在将 UserProfile 的用户字段定义为user = models.OneToOneField(settings.AUTH_USER_MODEL),并且 User.profile lambda 表达式保持不变。

4

6 回答 6

19

我不确定这里到底是什么问题,但一个问题肯定是你instance=request.user在实例化表单时通过了。这绝对是错误的:request.user是 User 的一个实例,而表单是基于UserProfile.

相反,你想做这样的事情:

f = UserDetailsForm(request.POST)
if f.is_valid():
    profile = f.save(commit=False)
    profile.user = request.user
    profile.save()

至于 ForeignKey vs OneToOne,你绝对应该使用 OneToOne。关于使用 ForeignKeys 的建议是在 Django 1 发布前一段时间给出的——现在差不多五年前了——因为 OneToOne 的原始实现很差,它应该被重写。您当然不会在此处找到任何建议使用 FK 的最新文档。

评论后编辑现在的问题是您正在使用第一个参数 data 实例化表单,即使请求不是 POST 并且因此request.POST是一个空字典。但是 data 参数,即使它是空的,也优先于作为初始数据传递的任何内容。

您应该回到在语句中实例化表单的原始模式- 但在子句中执行时请if确保不要通过。request.POSTelse

于 2013-08-17T09:04:34.273 回答
2

请记住将您的模型表格注册到admin.py文件中。这是一个常见的错误

在此处注册您的模型。

from . models import advancedUserForm
admin.site.register(advancedUserForm)
于 2019-06-29T08:55:46.760 回答
2

这是一种旧线程,但我希望这会对某人有所帮助。我一直在努力解决类似的问题,我从数据库启动对象,更新字段,调用 save() 函数,但什么也没发生。

user = User.objects.get(username = example_string)
user.userprofile.accepted_terms = True
user.userprofile.save()

最近添加了字段accepted_terms,这就是问题所在。首先尝试python manage.py makemigrationsand python manage.py migrate,如果这没有帮助您需要刷新数据库。

我的解决方案刷新数据库

于 2019-05-18T09:27:33.973 回答
0
UserDetailsForm(request.POST, instance = db_obj_form)

db_obj 应该是您要保存的表 UserProfile 的对象。

于 2013-08-17T09:20:48.967 回答
0

我认为您需要首先为 ModelForm 创建一个对象,然后在请求方法为 post 时分配该对象。在您的代码中,您只对一个属性执行此操作,并且在检查方法之前。- 同样在您的 forms.py 中,在 Meta() 类的 fields 参数中,您使用了 [] 括号来指示必须排除哪些属性,但是当您在表单中包含所有这些属性时,您必须使用 () 括号。我认为您的代码应编辑如下:

看这里

于 2020-05-21T15:36:33.503 回答
0

无论您尝试在哪里向 Django 代码提交表单数据,Django 都会为整个表单数据创建一个对象。对象看起来像这样form_obj = request.method_name。这method_name是(POST或GET)ex的表单方法:-form_obj = request.POST

如果要获取表单数据,请使用函数 request.method_name.get(name) 这里名称是表单属性赋值

前任:-

<form method="post">
{% csrf_token %}
{form}
</form>

在视图中:-

import statements as you required
def your_function(request):
  # you can creat a object to the form by
  form_obj = myform()
  if request.method =="POST":
    form_obj = myform(request.POST)
    if form_obj.is_valid():

      # you can directly save by use commit()
      form_obj.save(commit=True)
       #   or
      form_obj1 = form_obj.save(commit=False)
      #which  do you want to save in database ,those fields you need to specify like below 
      form_obj1.attribute1 = form_obj.cleaned_data["name of form field"]
        '
        '
      form_obj1.save()

并在 Myform.py 文件中

import statments    
class myform(forms.ModelForm):
    class meta():
        model = your_models_name
        fields =("attribute1","attribute2".....) # included attribute of your_model
于 2020-05-21T16:07:03.197 回答