フォームがすでに存在し、いくつかの列を更新するだけで、モデルフィールドセットでフォームフィールドを無効にするにはどうすればよいですか?新しいフォームがユーザーによって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
注:
これは 'ローカル変数 'インスタンスが'代入の前に参照される 'ことになります。インスタンスのインスタンスをインスタンス化する必要がありますか? –
インスタンスがインスタンス化されるとき、 'instance'が' instance'でなければならない問題を修正しました。私は前にこの解決策を試したことを誓う...カップルのキャラクターをオフにしているに違いない。ありがとうございました! –
ああ、私はその行の引用符を忘れてしまった。とにかくそれを稼働させたとしても、今修正しました。 –