我遇到以下视图和表单的问题。表单正确加载,但是当我编辑任何不保存的字段时。经过一些调试后,我认为这是由于以下两种情况之一:request.method == "POST"
评估为false,或form.is_valid()
评估为false。我的模板或clean()方法可能有问题吗?我搜索过以前的问题,找不到任何有用的东西。我还检查了我的clean()方法对Django文档并认为它没问题。
views.py
@login_required
def edit_transaction(request, pk):
transaction = get_object_or_404(Transaction, pk=pk)
if request.method == "POST":
form = TransactionForm(request.POST, instance=transaction)
if form.is_valid():
transaction = form.save(commit=False)
transaction.updated = timezone.now()
transaction.save()
return redirect('view_transaction_detail', pk=transaction.pk)
else:
form = TransactionForm(request=request, instance=transaction)
return render(request, 'budget/new_transaction.html', {'form': form})
forms.py
class TransactionForm(forms.ModelForm):
class Meta:
model = Transaction
fields = ('title', 'transaction_type', 'category', 'budgeted_amount', 'actual_amount', 'date', 'comments',)
#new_category field to allow you to add a new category
new_category = forms.CharField(max_length=30, required=False, label="New Category Title")
def __init__(self, request, *args, **kwargs):
super(TransactionForm, self).__init__(*args, **kwargs)
#category is now not a required field because you will use category OR new_category
self.fields['category'].required=False
#set to allow use of self.request.user to set user for category
self.request = request
def clean(self):
category = self.cleaned_data.get('category')
new_category = self.cleaned_data.get('new_category')
if not category and not new_category:
# raise an error if neither a category is selected nor a new category is entered
raise forms.ValidationError('Category or New category field is required')
elif not category:
# create category from new_category
category, created = Category.objects.get_or_create(title=new_category, defaults={'user': self.request.user})
self.cleaned_data['category'] = category
return super(TransactionForm, self).clean()
模板
{% extends 'budget/base.html' %}
{% block content %}
<h2>New transaction</h2>
<h4>To add a new category, leave Category blank and enter your new category in the New Category Title field</h4>
<form method="POST" class="post-form">
{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="save btn btn-default">Save</button>
</form>
{% endblock %}
更新以下答案 - 通过kwargs访问请求
def __init__(self, *args, **kwargs):
super(TransactionForm, self).__init__(*args, **kwargs)
self.fields['category'].required=False
self.request = kwargs.pop('request', None)
答案 0 :(得分:1)
正如我在上一个问题中所提到的,由于您已经更改了表单初始化方法的签名,因此您需要将两次的请求传递给实例化它。你不是在POST时才这样做的;因此,当它是POST时,Python会获取您传递的数据并将其分配给request
参数,从而使数据本身为空白。
form = TransactionForm(request, data=request.POST, instance=transaction)
注意正是因为这个原因,改变签名是个坏主意;相反,将request
作为关键字参数传递,并在方法内部从kwargs
获取。