我在模型中使用了自引用外键。在视图中,当我使用 form.cleaned_data.get('parent')
它返回 None
但当我用 request.POST.get('parent')
它返回的值。为什么要用 cleaned_data
在这里不能工作?
模型
class Category(models.Model):
parent = models.ForeignKey('self', blank=True, null=True, on_delete=models.SET_NULL)
slug = models.SlugField(unique=True, max_length=50)
title = models.CharField(max_length=255, unique=True)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
表格
class CreateCategoryForm(forms.ModelForm):
class Meta:
model = Category
fields = ['title', 'slug']
观点
def create_category(request):
form = CreateCategoryForm()
categories = Category.objects.order_by('-created')
if request.method == 'POST':
form = CreateCategoryForm(request.POST)
if form.is_valid():
# parent = request.POST.get('parent') # works
# parent = form.cleaned_data.get('parent') # returns None
category = form.save(commit=False)
category.parent = form.cleaned_data.get('parent')
category.save()
messages.success(request, 'Created Successfully.')
return redirect('list_categories')
return render(request, 'add_category.html', {'form':form, 'categories':categories})
模板
<form action="" method="post">
{% csrf_token %}
<div class="form-group">
<label>Category Name</label>
<input type="text" name="title" class="form-control"
value="{{form.title.value|default_if_none:''}}"/>
{% if form.title.errors %}
<span class="error">{{form.title.errors|striptags}}</span>
{% endif %}
</div>
<div class="form-group">
<label for="select" class="">Category Parent</label>
<select name="parent" id="exampleSelect"
class="form-control">
<option selected>Select</option>
{% for category in categories %}
<option value="{{category.pk}}">{{category.title}}</option>
{% endfor %}
</select>
</div>
所以,你的第一个问题,是你没有把字段包含在modelform中,所以要解决这个问题。
class CreateCategoryForm(forms.ModelForm):
class Meta:
model = Category
fields = ['title', 'slug', 'parent']
第二个问题是你自己在模板中渲染了表单字段 因此没有利用Django的属性处理功能。要修复这个问题。
<div class="form-group">
<label for="{{form.parent.id_for_label}}">Category Parent</label>
{{form.parent}}
</div>
现在select没有正确的html类 但我们可以把这个传递给表单字段 完整的解决方案。
class CreateCategoryForm(forms.ModelForm):
# ModelForm will take care of setting required to False
parent = forms.ModelChoiceField(queryset=Category.objects.order_by('-created'), attrs={'class': 'form-control'})
class Meta:
model = Category
fields = ['title', 'slug', 'parent']
# view
def create_category(request):
form = CreateCategoryForm()
if request.method == 'POST':
form = CreateCategoryForm(request.POST)
if form.is_valid():
category = form.save(commit=False)
category.parent = form.cleaned_data.get('parent')
category.save()
messages.success(request, 'Created Successfully.')
return redirect('list_categories')
return render(request, 'add_category.html', {'form':form})