当我使用自定义模型管理器时,为什么我的Django modelformset总是无效?

时间:2011-02-09 20:39:37

标签: django

将我的代码剥离到最低限度后,它仍然无法正常工作。我总是得到提示:

(Hidden field id) Select a valid choice. That choice is not one of the available choices.

这就是我的表格:

class ChangeItemForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(ChangeItemForm, self).__init__(*args, **kwargs)
        for key in self.fields:
            self.fields[key].required = False
        class Meta:
            model = Item
            fields = ('name','tags','no')

ChangeItemFormset=modelformset_factory(Item,extra=0,form=ChangeItemForm)

我的观点如下:

def manage_view(request):

    if request.method=='POST':  
        itemforms=ChangeItemFormset(request.POST,
                        queryset=Item.objects.filter(creator=request.user))
    else:
        itemforms=ChangeItemFormset(queryset=Item.objects.filter(creator=request.user))

    messages.info(request,str(itemforms.is_valid())) #always prints False

    context=RequestContext(request)
    context.update({'formset':itemforms,
                })
    return render_to_response('sonitem/test_forms.html',context)

在我的模板中我这样做:

<form action="." method="post" name="upload_image">
<button type="submit" name="action" value="change">change</button>
{%for form in formset.forms%}
    {{form}}
{%endfor%}
{{formset.management_form}}
{%csrf_token%}
</form>
messages:
{%for message in messages%}
    <div>{{message}}</div>
{%endfor%}

多数民众赞成。我不知道在哪里可以看得更远。也许我做错了?至少我肯定我错过了一个重要的模板集如何工作...如果有人可以帮助我。

修改
看起来它与我的模型项目有某种关系。刚刚创建了一个新的简化模型Item2,这段代码完全正常。 Item2只包含上面表格中的字段。回到项目:为什么(更重要的是 - 如何)不在formset中的modelfield会影响formset验证?

Item2模型,正在运行的模型:

class Item2(models.Model):
    name=models.CharField(max_length=50)
    tags=TagField()
    no=models.IntegerField(blank=True,null=True)
    creator = models.ForeignKey(User, related_name='creator')

EDIT2:
我想我已经包围了导致问题的原因:我已经将模型管理器定义为默认值,即寻找状态 - 这是一个models.IntegerField。只要我把它放到课堂上,它就会停止工作并准确传递上面的错误信息。 Item模型看起来像这样:

class Item(models.Model):
    PRIVATE_STATUS=1
    PUBLIC_STATUS=2
    RELEASED_STATUS=3
    STATUS_CHOICES=((PRIVATE_STATUS ,'private'),
                    (PUBLIC_STATUS  ,'public' ),
                    (RELEASED_STATUS,'released'))

    status = models.IntegerField(choices=STATUS_CHOICES,default=PRIVATE_STATUS)

    public = PublicItemManager()
    objects = models.Manager()

    name=models.CharField(max_length=50)
    tags=TagField()
    no=models.IntegerField(blank=True,null=True)
    file=models.FileField()
    creator = models.ForeignKey(User, related_name='creator')
    status=models.IntegerField(blank=True,null=True)

所以我必须在上面提出我的问题。是否可以在模型中使用状态(肯定是必填字段)并仍然使用formset? formset仅用于编辑,不用于创建项目。并且始终预先填充,没有机会出现空状态字段。

我仍然不明白表格中不存在的字段如何阻碍其验证。顺便说一句,如果我只使用ChangeItemForm,它就不会。

编辑3:
这是经理,剥离到最简单的版本导致麻烦:

class PublicItemManager(models.Manager):
        def get_query_set(self):
            return super(PublicItemManager,
                         self).get_query_set().filter(status=self.model.PUBLIC_STATUS)  

当我

#public=PublicItemManager  
一切顺利。

编辑4:
哦,顺便说一句:当我让查询集与对象管理器一起工作时,为什么公共管理员会影响任何验证?

queryset=Item.**objects**.filter(creator=request.user)  

1 个答案:

答案 0 :(得分:0)

在研究了django-docs很长一段时间后,我找到了解决方案。看起来在某些情况下,django创建的“自动”管理器不是_default_manager。文档在这里:http://docs.djangoproject.com/en/1.2/topics/db/managers/#controlling-automatic-manager-types

以下是工作经理的代码:

class PublicItemManager(models.Manager):  

    #this is the important line:
    use_for_related_fields = True  

    def get_query_set(self):
       return super(PublicItemManager,self).get_query_set().filter(status=self.model.PUBLIC_STATUS)