[英]Django ModelForm foreign key filtering
我正在尝试过滤模型表单中的外键字段选择,但表单无法正常工作。 我的脚本:
forms.py
from django import forms
from .models import Album, Song
class SongCreateForm(forms.ModelForm):
class Meta:
model = Song
fields = [
'album',
'name',
'is_favorite'
]
widgets = {
'album': forms.Select(attrs={'class': 'form-control'}),
'name': forms.TextInput(attrs={'class': 'form-control'}),
'is_favorite': forms.CheckboxInput(attrs={'class': 'form-check-input'}),
}
def __init__(self, user, *args, **kwargs):
super(SongCreateForm, self).__init__(*args, **kwargs)
self.fields['album'].queryset = Album.objects.filter(owner=user)
views.py
from django.views.generic import CreateView
class SongCreateView(CreateView):
template_name = 'music/song_create.html'
success_url = '/songs/'
def get_form(self, form_class=None):
form_class = SongCreateForm(user=self.request.user)
return form_class
print(form_class.errors.as_data())
print(form_class.is_valid())
song_create.html
{% extends 'base.html' %}
{% block content %}
<form method="post">{% csrf_token %}
{% if form.errors %}
<p>{{ form.errors }}</p>
{% endif %}
<div class="form-group">
<label for="{{ form.album.id_for_label }}">Album</label>
{{ form.album }}
</div>
<div class="form-group">
<label for="{{ form.name.id_for_label }}">Name</label>
{{ form.name }}
</div>
<div class="form-check">
<label for="{{ form.is_favorite.id_for_label }}" class="form-check-label">
{{ form.is_favorite }}Favorite
</label>
</div>
<button type="submit" class="btn btn-primary" value="Save">Add</button>
</form>
{% endblock %}
“专辑”字段的过滤查询集运行正常。 它仅显示与经过身份验证的用户相关联的专辑,但是当我单击表单浏览器中的“提交”时,不会将我重定向到成功网址,也不会将歌曲添加到数据库中。 我在views.py的末尾添加了两个print语句,以检查该表单是否有效并且有任何错误。 当form.errors返回空字典时 ,form.is_valid()等于False 。 如果Django没有任何错误,为什么将其视为无效?
注:SongCreateView工作顺利,当我在views.py注释掉初始化函数在forms.py和get_form功能。
首先,请在return
语句之后删除这些print
语句,因为在方法返回值之后它们将永远不会执行。 其次,将form_class
属性添加到您的视图类中,如下所示:
class SongCreateView(CreateView):
template_name = 'music/song_create.html'
success_url = '/songs/'
form_class = SongCreateForm
然后在get_form
方法中:
def get_form(self, form_class=None):
if form_class is None:
form_class = self.get_form_class()
return form_class(user=self.request.user, **self.get_form_kwargs())
然后重写form_valid
方法,将登录的用户与Song
实例相关联,如下所示:
def form_valid(self, form):
self.object = form.save(commit=False)
self.object.user = self.request.user
self.object.save()
return redirect(self.get_success_url())
从顶部的django.shortcuts
导入redirect
。 希望能帮助到你!
我的猜测是Song的ID丢失了。 当您使用神奇的代码
{{ form }}
尽管输入被隐藏,但该字段是自动添加的。 当您像执行操作一样手动定义所有字段时,必须确保添加了ID,即需要添加
{{ form.pk }}
或歌曲ID的名称(此处为pk)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.