2011-02-09 4 views
3

私のコードを最小限に抑えても、まだ動作しません。私はなかれヒントを得る:カスタムモデルマネージャを使用すると、私のDjango modelformsetが常に無効になるのはなぜですか?

(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は上記の形式のフィールドだけを持っていました。アイテムに戻る:なぜフォームセットに含まれていないmodelfieldがフォームセットの検証に影響を与えるのか(さらに重要なのは - どのように)ですか?

アイテム2モデル、働いている1:

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です。私はこれをクラスに入れるとすぐに、動作を停止し、上記のエラーメッセージを正確に配信します。 アイテムのモデルはやや次のようになります。

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はアイテムの作成ではなく、編集用です。 常にが事前入力されていますが、空のステータスフィールドが存在する可能性はありません。

フォームにさえいないフィールドがどのようにそれの検証を妨げることができるのかまだ分かりません。ちなみに、私は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) 
+0

http://docs.djangoproject.com/en/1.2/topics/db/managers/#controlling-automatic-manager-types

そしてここでは、作業マネージャーのためのコードです。あなたのフォームの '__init__'で必要な変更はありません。空白= Trueの場合は、フォームに必須ではありません。まずそれを試してから何が起こるかを見てみましょう... – dlamotte

+0

これまでにやったことがあります。 reflektに投稿を編集しました。そして、___init___で必要な変更は、Item2のためにうまくいきます。しかし、私はこれにもう一度飛び込みます。 – marue

+0

更新されたコードを投稿できますか? – dlamotte

答えて

0

かなり長い間django-docsを勉強して、解決策を見つけることができました。特定の状況のように、djangoは_default_managerではない「自動」なマネージャを作成します。ドキュメントはここにある:あなたが必要とされていないフィールドに「=空白の真の」追加することを検討することをお勧めします

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) 
関連する問題