ListField的Django-nonrel表单字段

问题描述

| 我正在appengine上试验ѭ0,并尝试使用ѭ1实现多对多关系。正如我在文档中看到的那样,您可以使用ѭ2来解决djamgo-nonrel不支持多对多关系的问题。 这是我的模型的摘录:
class MyClass(models.Model):
    field = ListField(models.ForeignKey(AnotherClass))
因此,如果我做对了,我将创建另一个类的外键列表,以显示与另一个类的多个实例的关系 使用这种方法,一切都可以正常工作。我可以在代码和视图中创建“ MyClass \”对象。但是,当我尝试使用管理界面时,出现以下错误
No form field implemented for <class \'djangotoolBox.fields.ListField\'>
因此,尽管我会尝试一些以前从未尝试过的事情。创建我自己的字段。好吧,实际上是我自己的表单,用于在管理界面中编辑“ 5”个实例。这是我所做的:
class MyClassForm(ModelForm):
    field = fields.MultipleChoiceField(choices=AnotherClass.objects.all(),widget=FilteredSelectMultiple(\"verbose_name\",is_stacked=False))
    class Meta:
        model = MyClass
然后我将“ 7”作为表单传递给管理界面
class MyClassAdmin(admin.ModelAdmin):
    form = MyClassForm

admin.site.register(MyClass,MyClassAdmin)
我虽然这行得通,但没有。当我进入管理界面时,会收到与以前相同的错误。任何人都可以在这里告诉我我在做什么错...或者如果您在管理界面中使用from11ѭ中的
ListField
SetField
等其他任何建议或成功案例,将不胜感激。     

解决方法

        好的,这就是我要做的所有工作... 我将从头开始 这就是我的模型的样子
class MyClass(models.Model):
    field = ListField(models.ForeignKey(AnotherClass))
我希望能够使用管理界面,通过为列表字段使用多个选择小部件来创建/编辑此模型的实例。因此,我创建了一些自定义类,如下所示
class ModelListField(ListField):
    def formfield(self,**kwargs):
        return FormListField(**kwargs)

class ListFieldWidget(SelectMultiple):
    pass

class FormListField(MultipleChoiceField):
    \"\"\"
    This is a custom form field that can display a ModelListField as a Multiple Select GUI element.
    \"\"\"
    widget = ListFieldWidget

    def clean(self,value):
        #TODO: clean your data in whatever way is correct in your case and return cleaned data instead of just the value
        return value
这些类允许在管理员中使用列表字段。然后,我创建了一个要在管理站点中使用的表单
class MyClassForm(ModelForm):
    def __init__(self,*args,**kwargs):
        super(MyClasstForm,self).__init__(*args,**kwargs)
        self.fields[\'field\'].widget.choices = [(i.pk,i) for i in AnotherClass.objects.all()]
        if self.instance.pk:
            self.fields[\'field\'].initial = self.instance.field

    class Meta:
        model = MyClass
完成此操作后,我创建了一个管理模型并将其注册到管理站点
class MyClassAdmin(admin.ModelAdmin):
    form = MyClassForm

    def __init__(self,model,admin_site):
        super(MyClassAdmin,self).__init__(model,admin_site)

admin.site.register(MyClass,MyClassAdmin)
现在这在我的代码中起作用。请记住,这种方法可能根本不适合google_appengine,因为我不太擅长它的工作方式,因此可能会产生效率低下的查询。     ,        据我了解,您正在尝试在django-nonrel中建立M​​2M关系,这不是开箱即用的功能。对于初学者来说,如果您想快速入门,可以使用此简单的类并使用
CharField
手动输入外键:
class ListFormField(forms.Field):
    \"\"\" A form field for being able to display a djangotoolbox.fields.ListField. \"\"\"

    widget = ListWidget

    def clean(self,value):
        return [v.strip() for v in value.split(\',\') if len(v.strip()) > 0]
但是,如果您希望从模型列表中进行多项选择,则必须使用ModelMultipleChoiceField,它在django-nonrel中也不起作用。这是我使用MultipleSelectField模拟M2M关系所做的工作: 假设您在两个类(分别为SomeClass和AnotherClass)之间具有M2M关系。您要在表单上为SomeClass选择关系。另外,我假设您想将引用作为SomeClass中的ListField保留。 (自然,您要按照此处的说明创建M2M关系,以防止在App Engine上工作时索引爆炸)。 因此,您的模型如下:
class SomeClass(models.Model):
    another_class_ids = ListField(models.PositiveIntegerField(),null=True,blank=True)
    #fields go here

class AnotherClass(models.Model):
    #fields go here
并以您的形式:
class SomeClassForm(forms.ModelForm):

    #Empty field,will be populated after form is initialized
    #Otherwise selection list is not refreshed after new entities are created.
    another_class = forms.MultipleChoiceField(required=False)

def __init__(self,**kwargs):
    super(SomeClassForm,**kwargs)
    self.fields[\'another_class\'].choices = [(item.pk,item) for item in AnotherClass.objects.all()]

    if self.instance.pk: #If class is saved,highlight the instances that are related
        self.fields[\'another_class\'].initial = self.instance.another_class_ids

def save(self,**kwargs):  
    self.instance.another_class_ids = self.cleaned_data[\'another_class\']         
    return super(SomeClassForm,self).save()

class Meta:
    model = SomeClass
希望这可以帮助您入门,我为普通表格实现了此功能,可以为管理面板进行调整不那么难。     ,        这可能无关紧要,但对于管理界面,请确保在设置中django.contrib.admin之后列出了djangotoolbox。.INSTALLED_APPS     ,        您可以通过查询模型对象避免使用自定义表单类
class ModelListField(ListField):
  def __init__(self,embedded_model=None,**kwargs):
  super(ModelListField,**kwargs)
  self._model = embedded_model.embedded_model

  def formfield(self,**kwargs):
    return FormListField(model=self._model,**kwargs)

class ListFieldWidget(SelectMultiple):
  pass

class FormListField(MultipleChoiceField):
  widget = ListFieldWidget

  def __init__(self,model=None,**kwargs):
    self._model = model
    super(FormListField,**kwargs)
    self.widget.choices = [(unicode(i.pk),i) for i in self._model.objects.all()]

  def to_python(self,value):
    return [self._model.objects.get(pk=key) for key in value]

  def clean(self,value):
    return value
    

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...