将数据从 ChoiceField 保存到数据库 Django
Save data from ChoiceField to database Django
我是 Django 的新手,我构建了一个显示单个 select 字段供选择的表单。字段中的数据由表单实时计算。
我现在需要在提交数据后保存在数据库中。唯一的问题是,出于某种原因,我得到了 IntegrityError error NOT NULL constraint failed: manager_playlist.user_id
下面是我在 Django 中的视图、表单和模型
views.py
def playlist(request):
if not is_user_already_auth_spotify(request):
messages.error(request, "You're not authenticated with Spotify, please authenticate here")
return redirect('/members/account/' + request.user.username)
if request.method == "POST":
form = ChoosePlaylistForm(request.POST, request=request)
if form.is_valid():
form.save()
messages.success(request, "Playlist successfully chosen")
return HttpResponseRedirect('account')
else:
pass
else:
form = ChoosePlaylistForm(request=request)
return render(request, 'show_playlist.html', {"playlist_choose_form": form})
forms.py
class ChoosePlaylistForm(ModelForm):
playlists = forms.ChoiceField(choices=())
class Meta:
model = Playlist
fields = ('playlists',)
def __init__(self, *args, request=None, **kwargs):
super(ChoosePlaylistForm, self).__init__(*args, **kwargs)
self.request = request
self.fields['playlists'].choices = self.generate_selection()
def generate_selection(self):
sp_auth, cache_handler = spotify_oauth2(self.request)
spotify = spotipy.Spotify(oauth_manager=sp_auth)
s_user = spotify.current_user()
u_playlists = spotify.user_playlists(s_user['id'], limit=10)
choices = []
for playlist in u_playlists["items"]:
if playlist["owner"]["id"] == s_user['id']:
playlist_choice = (playlist["id"], playlist["name"])
choices.append(playlist_choice)
else:
pass
return choices
model.py
class Playlist(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
playlists = models.CharField(max_length=50, null=True, blank=True) # playlists are the ids of the playlists
def __str__(self):
return self.playlists
错误原因是新建Playlist对象时,user字段不能为空(你没有加null=True,当然加了也没意义)。现在表单通过验证,因为表单不需要用户字段,只需要播放列表字段。你有几个选择。
选项 1
将必填字段添加到您的表单(我还没有测试过,请检查 docs!):
class ChoosePlaylistForm(ModelForm):
playlists = forms.ChoiceField(choices=())
class Meta:
model = Playlist
fields = ('playlists', 'user',) # NOTE THE CHANGE HERE
def __init__(self, *args, request=None, **kwargs):
super(ChoosePlaylistForm, self).__init__(*args, **kwargs)
self.request = request
self.user = request.user # Add the user to the form
选项 2
使用 commit=False 按原样保存表单,然后在保存模型之前添加缺少的字段:
if request.method == "POST":
form = ChoosePlaylistForm(request.POST, request=request)
if form.is_valid():
playlist = form.save(commit=False) # NOTE THE CHANGE HERE
playlist.user = request.user # Add the user to the partial playlist
playlist.save() # Now you can save the playlist
messages.success(request, "Playlist successfully chosen")
return HttpResponseRedirect('account')
选项 3
在实例化表单本身时添加字段(我不确定我的语法是否正确):
form = ChoosePlaylistForm(request.POST, request=request, instance=request.user)
编辑
上面的选项 3 似乎不起作用。我相信此编辑将:
form = ChoosePlaylistForm(request.POST, request=request, initial={'user': request.user})
我是 Django 的新手,我构建了一个显示单个 select 字段供选择的表单。字段中的数据由表单实时计算。
我现在需要在提交数据后保存在数据库中。唯一的问题是,出于某种原因,我得到了 IntegrityError error NOT NULL constraint failed: manager_playlist.user_id
下面是我在 Django 中的视图、表单和模型
views.py
def playlist(request):
if not is_user_already_auth_spotify(request):
messages.error(request, "You're not authenticated with Spotify, please authenticate here")
return redirect('/members/account/' + request.user.username)
if request.method == "POST":
form = ChoosePlaylistForm(request.POST, request=request)
if form.is_valid():
form.save()
messages.success(request, "Playlist successfully chosen")
return HttpResponseRedirect('account')
else:
pass
else:
form = ChoosePlaylistForm(request=request)
return render(request, 'show_playlist.html', {"playlist_choose_form": form})
forms.py
class ChoosePlaylistForm(ModelForm):
playlists = forms.ChoiceField(choices=())
class Meta:
model = Playlist
fields = ('playlists',)
def __init__(self, *args, request=None, **kwargs):
super(ChoosePlaylistForm, self).__init__(*args, **kwargs)
self.request = request
self.fields['playlists'].choices = self.generate_selection()
def generate_selection(self):
sp_auth, cache_handler = spotify_oauth2(self.request)
spotify = spotipy.Spotify(oauth_manager=sp_auth)
s_user = spotify.current_user()
u_playlists = spotify.user_playlists(s_user['id'], limit=10)
choices = []
for playlist in u_playlists["items"]:
if playlist["owner"]["id"] == s_user['id']:
playlist_choice = (playlist["id"], playlist["name"])
choices.append(playlist_choice)
else:
pass
return choices
model.py
class Playlist(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
playlists = models.CharField(max_length=50, null=True, blank=True) # playlists are the ids of the playlists
def __str__(self):
return self.playlists
错误原因是新建Playlist对象时,user字段不能为空(你没有加null=True,当然加了也没意义)。现在表单通过验证,因为表单不需要用户字段,只需要播放列表字段。你有几个选择。
选项 1
将必填字段添加到您的表单(我还没有测试过,请检查 docs!):
class ChoosePlaylistForm(ModelForm):
playlists = forms.ChoiceField(choices=())
class Meta:
model = Playlist
fields = ('playlists', 'user',) # NOTE THE CHANGE HERE
def __init__(self, *args, request=None, **kwargs):
super(ChoosePlaylistForm, self).__init__(*args, **kwargs)
self.request = request
self.user = request.user # Add the user to the form
选项 2
使用 commit=False 按原样保存表单,然后在保存模型之前添加缺少的字段:
if request.method == "POST":
form = ChoosePlaylistForm(request.POST, request=request)
if form.is_valid():
playlist = form.save(commit=False) # NOTE THE CHANGE HERE
playlist.user = request.user # Add the user to the partial playlist
playlist.save() # Now you can save the playlist
messages.success(request, "Playlist successfully chosen")
return HttpResponseRedirect('account')
选项 3
在实例化表单本身时添加字段(我不确定我的语法是否正确):
form = ChoosePlaylistForm(request.POST, request=request, instance=request.user)
编辑
上面的选项 3 似乎不起作用。我相信此编辑将:
form = ChoosePlaylistForm(request.POST, request=request, initial={'user': request.user})