代码之家  ›  专栏  ›  技术社区  ›  Pederduel

模型曼尼托曼尼菲尔德。all()给出AttributeError:“ManyToManyDescriptor”对象没有属性“all”

  •  1
  • Pederduel  · 技术社区  · 7 年前

    我正在使用Django 2.0.2、Python 3.6.4和PyCharm 2017.3.3

    模型:(in Models.py)

    class Position(models.Model):
        title = models.CharField(max_length=50)
        gang = models.ForeignKey(Gang, on_delete=models.CASCADE)
        description = models.TextField(max_length=20000)
    
        def __str__(self):
            return str(self.title) + ', ' + str(self.gang)
    
    class Application(models.Model):
        positions = models.ManyToManyField(Position)
        applicant = models.ForeignKey(User, on_delete=models.CASCADE)
    
    class Ranking(models.Model):
        position = models.ForeignKey(Position, on_delete=models.CASCADE)
        applicant = models.ForeignKey(User, on_delete=models.CASCADE)
        rank = models.IntegerField(default=3,validators=[
                MaxValueValidator(3),
                MinValueValidator(1)
            ])
    

    表单:(in forms.py)

    class RankingForm(forms.ModelForm):
        rank = forms.IntegerField(max_value=3, min_value=1)
        position = forms.ModelMultipleChoiceField(queryset=Application.positions.all())
    
        class Meta:
            model = Ranking
            exclude = ['applicant']
            fields = ('rank', 'position')
    
        def __init__(self, *args, **kwargs):
            super(RankingForm, self).__init__(*args, **kwargs)
            self.fields['rank'].widget.attrs.update({'class': 'form-control'})
    

    我一直从

    “position=forms.ModelMultipleChoiceField(queryset=Application.positions.all())”

    当我写作时

    class Application(models.Model):
        ... 
    
        def __str__(self):
            return str(self.positions.all())
    

    它在django admin中显示为QuerySet(适用于forms.ModelMultipleChoiceField()),但

        class Application(models.Model):
        ... 
    
        def __str__(self):
            return str(Application.positions.all())
    

    给我同样的错误:“ManyToManyDescriptor”对象没有属性“all”

        class RankingForm(forms.ModelForm):
            ...
            position = forms.ModelMultipleChoiceField(queryset=Position.objects.all())
    

    工作正常,但这不是我希望字段显示的内容。

    我想用特定应用程序中的所有位置创建一个ModelMultipleChoiceField(),但这个错误一直在妨碍我。似乎仅仅引用一个模型是行不通的,但引用自我却行不通??非常感谢您的帮助!:)

    顺便说一句,我还没有找到任何关于这个问题的好文档,但是 this 似乎是相关的\u描述符的代码。ManyToManyDescriptor所在的py

    2 回复  |  直到 7 年前
        1
  •  1
  •   jackotonye Dmit3Y    7 年前

    使用作为类的初始化实例的实例来计算关系。

    应用程序的实例。

    application = Application.objects.first()
    application.positions.all()
    

    初始化后更改表单queryset。

    class RankingForm(forms.ModelForm):
        rank = forms.IntegerField(max_value=3, min_value=1)
        position = forms.ModelMultipleChoiceField(queryset=Positions.objects.none())
    
        class Meta:
            model = Ranking
            exclude = ['applicant']
            fields = ['rank', 'position']
    
        def __init__(self, *args, **kwargs):
            super(RankingForm, self).__init__(*args, **kwargs)
            self.fields['rank'].widget.attrs.update({'class': 'form-control'})  
            self.fields['position'].queryset = self.instance.positions.all()
    
        2
  •  0
  •   Blender    7 年前

    您可以访问模型的当前实例 ModelForm 对象正在使用 instance 属性然后可以使用它在中创建正确的查询集 __init__ :

    class RankingForm(forms.ModelForm):
        ...
    
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
            self.fields['rank'].widget.attrs.update({'class': 'form-control'})
            self.fields['position'].queryset = self.instance.positions.all()