Django ModelForm外键过滤

我试图在我的模型表单中过滤外键字段选择,但表单不起作用。 我的脚本:

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 %}

过滤“专辑”字段的查询集正常工作。 它只显示与已验证用户相关的相册,但当我单击表单提交时,浏览器不会将我重定向到成功url,并且歌曲不会添加到数据库中。 我在views.py的最后添加了两个打印语句来检查该表单是否有效并且有任何错误。 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 。 希望能帮助到你!


我的猜测是歌曲的ID缺失。 当你使用魔法代码的时候

{{ form }}

虽然输入被隐藏,但是该字段会自动添加。 当你像所做的那样手动定义所有字段时,你将不得不确保ID被添加,这是你需要添加的

{{ form.pk }}

或者是你歌曲的id的名字(这里是pk)。

链接地址: http://www.djcxy.com/p/56507.html

上一篇: Django ModelForm foreign key filtering

下一篇: How can I refactor this django query to not select each individual object?