2017-08-21 9 views
2

フォームがすでに存在し、いくつかの列を更新するだけで、モデルフィールドセットでフォームフィールドを無効にするにはどうすればよいですか?新しいフォームがユーザーによってformsetに追加されますか?Django - Formsetで既存のフォームの編集を無効にするが、新しいフォームでの編集を許可する

models.py:

from django.db import models 
from django.utils import timezone 

class MyModel(models.Model): 
    idno = models.CharField(max_length=20) 
    date = models.DateTimeField(default=timezone.now) 
    entity = models.CharField(max_length=50) 
    logic = models.CharField(max_length=100) 
    choices = (
     ('1', 'Choice1'), 
     ('2', 'Choice2'), 
     ('3','Choice3'), 
    ) 
    choices = models.CharField(
     max_length=20, 
     choices=choices, 
     null=True, 
     ) 
    comment = models.CharField(max_length=500, null=True) 
    def __str__(self): 
     return self.idno 

forms.py:

from .models import MyModel 
from django.forms import modelformset_factory, ModelForm 

class MyForm(ModelForm): 

    class Meta: 
     model = MyModel 
     fields = '__all__' 

    def __init__(self, *args, **kwargs): 
     super(MyForm, self).__init__(*args, **kwargs) 
     self.fields['idno'].disabled = True 
     self.fields['date'].disabled = True 
     self.fields['entity'].disabled = True 
     self.fields['logic'].disabled = True 

MyFormSet = modelformset_factory(MyModel, extra=1, exclude=(), form=MyForm) 

views.py:

from django.shortcuts import render 
from django.http import HttpResponseRedirect 
from .models import Alert 
from .forms import AlertFormSet 
from django.contrib import messages 

def index(request): 
    newAlerts = MyModel.objects.filter(choices__isnull=True) 
    modelformset = MyFormSet(request.POST or None, queryset=newAlerts) 
    context = {'modelformset':modelformset} 
    if request.method == 'POST': 
     for form in modelformset: 
      if form.is_valid(): 
       if form.has_changed(): 
        form.save() 
        idno = form.cleaned_data['idno'] 
        entity = form.cleaned_data['entity'] 
        messages.success(request, 'idno %s for %s was saved' % (idno, entity)) 
     return HttpResponseRedirect('/') 
    return render(request, 'selfserve/index.html', context) 

のindex.html:

<form method="post" action=""> 
    {% csrf_token %} 
    {{ modelformset.management_form }} 
<div id="form_set"> 
    {% for form in modelformset %} 
     <table class='no_error'> 
      {{ form.as_table }} 
     </table> 
    {% endfor %} 
</div> 
<input type="button" value="Add More" id="add_more"> 
<input type="submit" value="Submit"> 
<div id="empty_form" style="display:none"> 
    <table class='no_error'> 
     {{ modelformset.empty_form.as_table }} 
    </table> 
</div> 
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> 
<script> 
    $('#add_more').click(function() { 
     var form_idx = $('#id_form-TOTAL_FORMS').val(); 
     $('#form_set').append($('#empty_form').html().replace(/__prefix__/g, form_idx)); 
     $('#id_form-TOTAL_FORMS').val(parseInt(form_idx) + 1); 
    }); 
</script> 
{% if messages %} 
<ul class="messages"> 
    {% for message in messages %} 
    <li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</li> 
    {% endfor %} 
</ul> 
{% endif %} 
</form> 

現時点では、ユーザーが[追加]ボタンをクリックして新しいフォームを追加すると、既存のフォームで無効にしたいフィールドも無効になります。私はこの質問を見た:In a Django form, how do I make a field readonly (or disabled) so that it cannot be edited?。しかし、私は解決策の両方の要素を組み合わせる方法を理解していません:field.disabled = django> 1.9でTrue、formsetの既存のフォームと新しいフォームを区切るifステートメント私はまた、可能性のあるオプションとして_construct_formメソッドについて聞いたことがありますが、私はModel Form作成のif文がより洗練されて分かりやすくなると思います。

ご迷惑をおかけして申し訳ありませんが、ありがとうございます。あなただけのすべてのフィールドが必要とされているため、インスタンスが存在してチェックすることにより、これを行うことができます

class MyForm(ModelForm): 

    class Meta: 
     model = MyModel 
     fields = '__all__' 

    def __init__(self, *args, **kwargs): 
     super(MyForm, self).__init__(*args, **kwargs) 
     instance = getattr(self, 'instance', None) 
     if instance and instance.pk: 
      self.fields['idno'].disabled = True 
      self.fields['date'].disabled = True 
      self.fields['entity'].disabled = True 
      self.fields['logic'].disabled = True 

注:

答えて

1

は、あなたがにリンク質問に技術を使用することができますように私には思えます。それらのうちのいくつかがそうでない場合は、それぞれに価値があるかどうかを確認する必要があります。

+0

これは 'ローカル変数 'インスタンスが'代入の前に参照される 'ことになります。インスタンスのインスタンスをインスタンス化する必要がありますか? –

+0

インスタンスがインスタンス化されるとき、 'instance'が' instance'でなければならない問題を修正しました。私は前にこの解決策を試したことを誓う...カップルのキャラクターをオフにしているに違いない。ありがとうございました! –

+0

ああ、私はその行の引用符を忘れてしまった。とにかくそれを稼働させたとしても、今修正しました。 –

関連する問題