【问题标题】:Reference objects using foreign keys in Django forms在 Django 表单中使用外键引用对象
【发布时间】:2015-02-16 10:35:29
【问题描述】:

我对我面临的问题进行了大量搜索,但找不到合适的解决方案。我是 Django 初学者

我正在创建一个项目,其中用户将能够提出一个愿望,而其他用户将被分配该愿望,然后他们可以绘制并提交。

我创建了用于询问和获得愿望的视图,但在提交愿望草图时遇到了问题。我不知道如何在 add_sketch 表单中只为当前用户显示这些愿望,然后用这个新草图更新草图模型。 现在我只是为上传的草图使用一个 charField。这是代码

models.py

class Wish(models.Model):

    content = models.CharField(max_length=500)
    wisher = models.ForeignKey(User)
    created_on = models.DateTimeField(auto_now_add=True)
    locked = models.BooleanField(default=False)

    class Meta():
        verbose_name_plural = 'Wishes'

    def __unicode__(self):
        return self.content



class Sketch(models.Model):

    wish = models.ForeignKey(Wish)
    sketcher = models.ForeignKey(User)
    image_temp = models.CharField(max_length=128)
    likes = models.IntegerField(default=0)
    assigned_on = models.DateTimeField(auto_now_add=True)
    submitted_on = models.DateTimeField(auto_now=True)

    class Meta():
        verbose_name_plural = 'Sketches'

    def __unicode__(self):
        return "Sketch for \""+ self.wish.content + "\""

views.py

@login_required
def add_sketch(request):
    if request.method == "POST":
        sketch_form = SketchForm(request.POST)

        if sketch_form.is_valid():
            add_sketch = sketch_form.save(commit=False)
            add_sketch.save()

            return sketchawish(request)

        else:
            print sketch_form.errors

    else:
        sketch_form = SketchForm()

    return render(request, 'saw/add_sketch.html', {'sketch_form': sketch_form})

这是forms.py

class GetWishForm(forms.ModelForm):
    wish = forms.ModelChoiceField(queryset= Wish.objects.filter(pk__in = Wish.objects.filter(locked=False)[:3].values_list('pk')), initial=0)

    class Meta:
        model = Sketch
        fields = ('wish',)

class SketchForm(forms.ModelForm):
    wish = forms.ModelChoiceField(queryset= Sketch.objects.all(), initial=0)
    image_temp = forms.CharField(help_text='Imagine this is an upload button for image, write anything')

    class Meta:
        model = Sketch
        fields = ('wish', 'image_temp')

更新:

我根据@almalki 的建议编辑了代码

forms.py

class SketchForm(forms.ModelForm):
    wish = forms.ModelChoiceField(queryset= Sketch.objects.all(), initial=0)
    image_temp = forms.CharField(help_text='Imagine this is an upload button for image, write anything')

    def __init__(self, *args, **kwargs):
        super(SketchForm, self).__init__(*args, **kwargs)
        self.fields['wish'].queryset = kwargs.pop('wish_qs')

    class Meta:
        model = Sketch
        fields = ('wish', 'image_temp')

views.py

@login_required
def add_sketch(request):
    if request.method == "POST":
        sketch_form = SketchForm(request.POST)

        if sketch_form.is_valid():
            add_sketch = sketch_form.save(commit=False)
            add_sketch.save()

            return sketchawish(request)

        else:
            print sketch_form.errors

    else:
        sketch_form = SketchForm(wish_qs=Wish.objects.filter(wisher=request.user))


    return render(request, 'saw/add_sketch.html', {'sketch_form': sketch_form})

我仍然收到错误 init() got an unexpected keyword argument 'wish_qs'

更新 2:

forms.py 和上面一样,我认为views.py 应该是这样的

@login_required
def add_sketch(request):
    if request.method == "POST":
        sketch_form = SketchForm(request.POST, wish_qs=Sketch.objects.filter(sketcher=request.user))

        if sketch_form.is_valid():
            add_sketch = sketch_form.save(commit=False)
            add_sketch.save()

            return sketchawish(request)

        else:
            print sketch_form.errors

    else:
        sketch_form = SketchForm(wish_qs=Sketch.objects.filter(sketcher=request.user))


    return render(request, 'saw/add_sketch.html', {'sketch_form': sketch_form})

当我选择一个愿望并点击提交时,错误是:annot assign "": "Sketch.wish" must be a "Wish" instance。 我知道这是因为模型需要一个 Wish 实例,但我们给出了一个 Sketch 实例,但我不知道如何实现我需要的。我认为需要在 models.py 中进行一些更改,将 Wish 和 Sketch 可逆地连接起来。

【问题讨论】:

  • 我的错误,检查更新的init,应该在调用super之前弹出参数
  • 谢谢!虽然这没有显示任何错误,并允许我在表单中使用登录用户,但结果不是我想要的。这向我显示了用户希望的愿望列表,而不是他被分配为其制作草图的愿望!请找出一些解决方案,我正在更新 OP,我认为代码应该是什么样子,以及它现在给我的错误。
  • 请帮助,如果不解决这个问题,我将无法继续我的项目!

标签: python django django-models django-forms django-views


【解决方案1】:

需要覆盖表单初始化中设置的字段查询:

class SketchForm(forms.ModelForm):
    wish = forms.ModelChoiceField(queryset= Sketch.objects.all(), initial=0)
    image_temp = forms.CharField(help_text='Imagine this is an upload button for image, write anything')

    def __init__(self, *args, **kwargs):
        wish_qs = kwargs.pop('wish_qs')
        super(SketchForm, self).__init__(*args, **kwargs)
        self.fields['wish'].queryset = wish_qs

    class Meta:
        model = Sketch
        fields = ('wish', 'image_temp')

在您看来,您需要传递一个根据当前登录用户过滤的查询集:

sketch_form = SketchForm(request.POST, wish_qs=Wish.objects.filter(wisher=request.user))

和:

sketch_form = SketchForm(wish_qs=Wish.objects.filter(wisher=request.user))

【讨论】:

  • 这给了我错误 __init__() 恰好需要 1 个参数(3 个给定)。我在哪里放置sketch_form = SketchForm(wish_qs=Wish.objects.filter(wisher=request.user))?感谢您的帮助!
  • @ketanbhatt 它应该在您的 add_sketch 视图中,我更新了 init 以处理位置参数 *args
  • 请检查更新,它仍然显示错误 __init__() got an unexpected keyword argument 'wish_qs'
猜你喜欢
  • 2013-07-17
  • 2012-06-03
  • 1970-01-01
  • 1970-01-01
  • 2016-04-09
  • 2022-06-25
  • 2020-12-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多