0

リストを使用して、モデルフォームの外部キー インスタンスを制限しようとしています。

ここに私のモデルがあります:

class Voicemail(models.Model):
    internalline = models.ForeignKey(InternalLine)
    person = models.ForeignKey(Person)

次に、対応するモデルフォームのinitメソッドで私が持っている

class VoicemailForm(ModelForm):
 def __init__(self, *args, **kwargs):
  ....
  ....
 # self.fields['internalline'].queryset = self.person.getPersonLines()  # this throws error in template.
   self.fields['internalline'].queryset = self.person.line.all()

   print(self.person.getPersonLines())
   print(self.person.line.all())

2 つの出力は同じ出力を出力します。

[<InternalLine: 1111>, <InternalLine: 5555>]
[<InternalLine: 1111>, <InternalLine: 5555>]

getPersonLines では、追加のロジックを実行して、行のリストを返します。

def getPersonLines(self):
    lines = []
    for line in self.line.order_by('extension'):
        lines.append(line)
    for phone in self.phonesst_set.all():
        for line in phone.line.order_by('extension'):
            if line not in lines:               
                lines.append(line)   

    return lines

テンプレートでレンダリングしようとすると、getPersonLines によって返されたリストを使用すると、エラーが発生します。

Caught AttributeError while rendering: 'list' object has no attribute 'all'

しかし、self.person.line.all() を使用してクエリセットを設定すると、同じことが機能します。

リストを使用してクエリセットに入力しようとしているときに、何か不足していますか?

前もって感謝します!!

アップデート

これがスタックトレースです

self.fields['internalline'].choices = self.person.getPersonLines()  

Traceback (most recent call last):
File "<console>", line 1, in <module>
File "C:\Python26\lib\site-packages\django\utils\encoding.py", line 27, in __str__
    return self.__unicode__().encode('utf-8')
File "C:\Python26\lib\site-packages\django\forms\forms.py", line 95, in __unicode__
    return self.as_table()
File "C:\Python26\lib\site-packages\django\forms\forms.py", line 217, in as_table
    errors_on_separate_row = False)
File "C:\Python26\lib\site-packages\django\forms\forms.py", line 180, in _html_output
   'field': unicode(bf),
File "C:\Python26\lib\site-packages\django\forms\forms.py", line 408, in __unicode__
   return self.as_widget()
File "C:\Python26\lib\site-packages\django\forms\forms.py", line 439, in as_widget
   return widget.render(name, self.value(), attrs=attrs)
File "C:\Python26\lib\site-packages\django\forms\widgets.py", line 516, in render
   options = self.render_options(choices, [value])
File "C:\Python26\lib\site-packages\django\forms\widgets.py", line 533, in render_options
for option_value, option_label in chain(self.choices, choices):
TypeError: 'InternalLine' object is not iterable

更新 2:

これが全体の__init__方法です

class VoicemailForm(ModelForm):

def __init__(self, *args, **kwargs):
   try: 
        self.person = kwargs.pop('person', None)
        super(VoicemailForm, self).__init__(*args, **kwargs)
        for field in self.fields:
            self.fields[field].widget.attrs['class'] = 'required_field'

        print(self.person.getPersonLines())
        print(self.person.line.all())
        if self.person:
            self.fields['internalline'].choices = self.person.getPersonLines()  
            #self.fields['internalline'].queryset = self.person.line.all()

   except Exception as e:
       print("Error overwriting __init__ of VoicemailForm")
       print(e)    

これが私のフォームの呼び出し方です

voicemail = VoicemailForm(person=person, prefix='voicemail')

更新 3 次のように django フォームを作成しようとしました。

class test(forms.Form):
 line = forms.ChoiceField()
 def __init__(self, *args, **kwargs):
        super(test, self).__init__(*args, **kwargs)
        self.fields['line'].choices=person.getPersonLines()

しかし、私は同じエラーが発生し続けます for option_value, option_label in chain(self.choices, choices): TypeError: 'InternalLineSST' object is not iterable

それから私は次のようなものに疲れました:

test = [1,2,3]
class myform(forms.Form):
    line = forms.ChoiceField()
    def __init__(self, *args, **kwargs):
        super(myform, self).__init__(*args, **kwargs)
        self.fields['line'].choices = test

>>> form = myform()
>>>print(form)

同様のエラーが表示されます

File "C:\Python26\lib\site-packages\django\forms\forms.py", line 439, in as_widget
 return widget.render(name, self.value(), attrs=attrs)
File "C:\Python26\lib\site-packages\django\forms\widgets.py", line 516, in render
 options = self.render_options(choices, [value])
File "C:\Python26\lib\site-packages\django\forms\widgets.py", line 533,in render_options
for option_value, option_label in chain(self.choices, choices):
TypeError: 'int' object is not iterable`

ここで何か不足していますか?

4

2 に答える 2

0

.all()とメソッドはどちらも.order_by()Djangoクエリセットの一部です。それらはPythonリストと同じではありません。表現は同じですが、実際には異なります。

Django ModelChoiceFieldの一部のコードは、結果のリストではなく、外部キーにクエリセットがあることを想定しています。代わりに設定self.fields['internalline'].choicesすると、この問題は発生しません。

代わりにこれを試してください:

self.fields['internalline'].choices = self.person.getPersonLines()
于 2012-08-30T16:53:54.317 に答える
0

私の目的は、リストを使用することでした。2つのクエリセットをマージして、外部キーのオプションを表示したかったのです。

に基づく

https://groups.google.com/forum/?hl=en&fromgroups=#!topic/django-users/0i6KjzeM8OI

リストの代わりにクエリセットを返すようにメソッドを変更しました。

def getPersonLines(self):
    vm_lines = self.line.all()
    for phone in self.phonesst_set.all():
        vm_lines = vm_lines | phone.line.all()

フォームの__inti__メソッドでは、クエリセットを使用できます

self.fields['internalline'].queryset = self.person.getPersonLines()
于 2012-09-05T23:09:45.157 に答える