【问题标题】:Set form field value before is_valid()在 is_valid() 之前设置表单字段值
【发布时间】:2013-06-25 17:50:15
【问题描述】:

我在掌握如何执行此操作时遇到了一些麻烦。我已尽最大努力在 Google 上搜索,但没有任何运气。

我将从一些代码开始,并解释我正在尝试做的事情:

models.py

class Action(models.Model):
    title = models.CharField(max_length=200)
    owner = models.ForeignKey(User, related_name='actions')
    created_by = models.ForeignKey(User, related_name='+', editable=False)
    modified_by = models.ForeignKey(User, related_name='+', editable=False)

class ActionForm(ModelForm):
    class Meta:
        model = Action

views.py

默认情况下,所有者有一个下拉字段。我有一个图标,允许用户在文本字段中输入新用户名而不是所有者。我检查owner_new 是否已提交,如果是,则创建该用户。然后我需要将owner 字段设置为该值,以便form.is_valid() 为真。

def action_create(request):
    if request.method == 'POST':
        form = ActionForm(request.POST)
        # check if new user should be created
        if 'owner_new' in request.POST:
            # check if user already exists
            user = User.objects.get(username=request.POST.get('owner_new'))
            if not user:
                user = User.objects.create_user(request.POST.get('owner_new'))
            # HERE IS WHERE I'M STUMPED
            form.owner = user.id
        if form.is_valid(): # THIS FAILS BECAUSE form.owner ISN'T SET
            action = form.save(commit=False)
            action.created_by = request.user
            action.modified_by = request.user
            action.save()
            return redirect('action_register:index')
    else:
        form = ActionForm()
    return render(request, 'actions/create.html', {'form': form})

【问题讨论】:

标签: django django-forms


【解决方案1】:

你可以试试这个:

def action_create(request):
    if request.method == 'POST':
        form = ActionForm(request.POST)
        # check if new user should be created
        if 'owner_new' in request.POST:
            # check if user already exists
            user, _ = User.objects.get_or_create(username=request.POST.get('owner_new'))                

            updated_data = request.POST.copy()
            updated_data.update({'owner': user}) 
            form = MyForm(data=updated_data) 

        if form.is_valid(): # THIS FAILS BECAUSE form.owner ISN'T SET
            action = form.save(commit=False)
            action.created_by = request.user
            action.modified_by = request.user
            action.save()
            return redirect('action_register:index')
    else:
        form = ActionForm()
    return render(request, 'actions/create.html', {'form': form})

更简洁的方法是:

required=False 添加到owner 字段。 现在,

if form.is_valid(): # THIS DOES NOT FAIL EVEN IF form.owner ISN'T SET
    action = form.save(commit=False)
    if 'owner_new' in request.POST:
        user, _ = User.objects.get_or_create(username=request.POST.get('owner_new'))                
        action.owner = user
    action.created_by = request.user
    action.modified_by = request.user
    action.save()
    return redirect('action_register:index')

【讨论】:

  • 首先,感谢您展示get_or_create() 功能。我不知道那存在。其次,我收到form.data['owner'] = user 的错误This QueryDict instance is immutable,这是我一直遇到的问题。 Django 真的不希望我弄乱这些值。
  • 是的,非常感谢您的帮助。一个小的变化是updated_data.update('owner', 'user') 必须被称为updated_data.update(owner=user)
【解决方案2】:

我遇到了类似的情况,不知道如何按照我想要的方式去做。我最终得到的是一个指向UserForm 的链接,它允许用户创建一个新的owner,然后在实例化表单时重定向回ActionForm,其中包含参数initial={owner: new_owner}

【讨论】:

    猜你喜欢
    • 2014-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-19
    • 2017-05-07
    相关资源
    最近更新 更多