1

modelform_factory を使用して、追加のフォームを含むモデルフォームを生成します。インスタンスを含むフォームの場合、タイプ フィールドは無効になり、追加のフォームの場合、フィールドは有効になります。

save() では、無効なフィールドの POST にデータがないため、フォームは検証されません。カスタムの clean メソッドでさえ機能しません (この回答を参照してください)。無効なフィールドの検証をスキップするか、このフィールドのインスタンス データを保持する方法が必要です。

models.py

class Attribute(models.Model):
    shapefile = models.ForeignKey(Shapefile)
    name = models.CharField(max_length=255)
    type = models.IntegerField()
    width = models.IntegerField()
    precision = models.IntegerField()

    def __unicode__(self):
        return self.name

フォーム.py

FIELD_TYPE = [('', '--Choose a type--'),
                    (0, 'Integer'),
                    (1, 'Integer list'),
                    (2, 'Double Precision Float'),
                    (3, 'List of doubles'),
                    (4, 'String of ASCII chars'),
                    (5, 'Array of strings'),
                    (8, 'Raw Binary data'),
                    (9, 'Date'),
                    (10, 'Time'),
                    (11, 'Date and Time')]

class AttributeForm(ModelForm):
    def __init__(self, *args, **kwargs):
        super(AttributeForm, self).__init__(*args, **kwargs)
        instance = getattr(self, 'instance', None)
        if instance and instance.pk:
            self.fields['type'].widget.attrs['disabled'] = True
            self.fields['width'].widget.attrs['readonly'] = True
            self.fields['precision'].widget.attrs['readonly'] = True

    type = forms.ChoiceField(choices=FIELD_TYPE)

    class Meta:
        model = Attribute
        exclude = ['shapefile']

ビュー.py

def editFields(request, shapefile_id):
    layer_selected = Shapefile.objects.get(pk=shapefile_id)
    attributes_selected= Attribute.objects.filter(shapefile__pk=shapefile_id)
    attributesFormset = modelformset_factory(Attribute, form=AttributeForm, extra=1, can_delete=True)
    if request.POST:
        formset = attributesFormset(request.POST, queryset=attributes_selected)
        formset.save()
    else:
        formset = attributesFormset(queryset=attributes_selected)

    return render_to_response("ezmapping/editFields.html", {'shapefile': layer_selected, 'formset':formset}, context_instance=RequestContext(request))
4

1 に答える 1

5

そこには多くのアプローチがありますが、これはかなりエレガントだと思います(実際に機能すると仮定すると、最初の検査では正しく見えますが、テストしていません)。

https://stackoverflow.com/a/5994681/2337736

フォームで、フィールドを条件付きで不要に設定し、カスタムの clean メソッドを宣言します。

def __init__(self):
    # as above, until here
        self.fields['type'].widget.attrs['disabled'] = True
        self.fields['type'].required = False
    # then continue as above

def clean_type(self):
    if self.instance and self.instance.pk:
        return self.instance.type
    else:
        return self.cleaned_data['type']

必須ではないと設定すると、そのフィールドの検証中にフィールドがすぐに短絡しないことを意味し、フィールドのカスタム clean メソッドはインスタンスの未変更の値を返すためNone、変更されたインスタンスをフォームから構築するときにオーバーライドされません。カスタム clean メソッドは、空の値または値がまったく指定されていない必須フィールドに対しては呼び出されません。

于 2013-09-25T17:04:12.413 に答える