如何在Django 1.7的表单模型中获取当前已登录用户的ID?

3
假设我有一个展示歌曲的网页。有公共和私人歌曲。公共歌曲可供所有人查看,而私人歌曲是某个用户创建的仅供该用户查看的歌曲。因此,用户应只能查看owner_id == NULL和owner_id ==当前登录用户ID(即他自己的ID)的歌曲。
模型:
import ....

    class Song(models.Model):
        name = models.CharField(max_length=100)    
        duration = models.IntegerField(max_length=15)
        owner = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True)

        def __unicode__(self):
            return self.name

查看:

from django.shortcuts import render, redirect, get_object_or_404
from django.contrib.auth.decorators import login_required
from songapp.models import Song
from songapp.forms import SongInfoForm

@login_required
def song_info(request):
    song = get_object_or_404(Box)
    song_status = song.get_status()
    form = SongInfoForm(initial={'song_list': song.song_list})

    return render(request, 'songapp/song_info.html',
        {'form': form, 'song': song, 'song_status': song_status})

表单:

    from django import forms
    from django.forms import ModelChoiceField

    from songapp.models import Song


    class SongInfoForm(forms.Form):

-->     selected_songs = Song.objects.filter(owner=None) | Song.objects.filter(owner=3)
        song_list = ModelChoiceField(queryset=selected_songs, required=False)

注意表单文件中箭头所指的那一行。这就是问题所在。虽然代码现在可以运行,但

(owner = 3)

是硬编码的。我知道我的用户 id 是 3。但是我希望它能正常工作。应该像这样:

(owner = currently_logged_in_user.id)

我还非常新手使用 Django 和 Python,不知道如何将用户 id 传递给 SongInfoForm 表单模型。

2个回答

5
我明白了。
在views.py文件中更改如下内容:
form = SongInfoForm(initial={'song_list': song.song_list}, user=request.user)

感谢之前的回答和这个例子django表单:从view.py传递参数到forms会出错,我想到了这个解决方案,它完美地工作。

在forms.py中:

class SongInfoForm(forms.Form):
    def __init__(self, *args, **kwargs):
        user = kwargs.pop('user')
        super(SongInfoForm, self).__init__(*args, **kwargs)
        self.fields['song_list'] = forms.ModelChoiceField(queryset=Song.objects.filter(owner=None) | Song.playlist.objects.filter(owner=user), required=False)

0

好的,我的错。 没有仔细阅读,没有看到问题在表单中,但根据这篇文章:https://dev59.com/n2435IYBdhLWcg3w9E9Y#5122029,你可以像这样重写你的for循环:

class SongInfoForm(forms.Form):
    def __init__(self, user, *args, **kwargs):
        self.user = user
        super(SongInfoForm, self).__init__(*args, **kwargs)

    selected_songs = Song.objects.filter(owner=None) | Song.objects.filter(owner=user.id)
    song_list = ModelChoiceField(queryset=selected_songs, required=False)

然后在视图中创建您的表单,如下所示:

form = SongInfoForm(request.user, initial={'song_list': song.song_list})

这样表单对象应该可以访问用户。


我遇到了一个错误:“名称'request'未定义”。我之前尝试过这个,但没有成功。也许我需要像“from django.http import HttpRequest”这样做一个导入?请记住我对此非常陌生。 - Saša Kalaba
不,因为在这里将对象传递给视图:def song_info(request):,并且由于您在render中使用它:return render(request, 'songapp/song_info.html', [...],所以它应该可以工作。如果您正在使用带有调试的./manage.py runserver,则应该会出现完整的跟踪问题的信息。由于我的答案直接来自Django 1.7文档,我不明白为什么会被投票反对。 - Dawid
我没有给你点踩,但是这里有一个赞来平衡一下 :/。异常位置报告显示问题在forms.py文件中,与上面指定的确切行相同。还是不起作用,但感谢你的尝试。 - Saša Kalaba
1
@Dawid 不行,这不可能起作用。那行代码不在视图或模板中,而是在表单类的定义中。在那里无法访问请求。 - Daniel Roseman
我自己在半小时内找到了这个解决方案,但仍然出现错误。我按照您发布的代码进行了修改,但在“form = SongInfoForm(request.user, initial={'song_list': song.song_list})”行中出现了“名称'user'未定义”的错误。 - Saša Kalaba

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接