Thay đổi trường biểu mẫu Django thành trường ẩn


128

Tôi có một mẫu Django với một RegexField, rất giống với một trường nhập văn bản bình thường.

Theo quan điểm của tôi, trong một số điều kiện nhất định, tôi muốn ẩn nó khỏi người dùng và cố gắng giữ biểu mẫu giống nhau nhất có thể. Cách tốt nhất để biến lĩnh vực này thành một HiddenInputlĩnh vực là gì?

Tôi biết tôi có thể đặt thuộc tính trên trường bằng:

form['fieldname'].field.widget.attr['readonly'] = 'readonly'

Và tôi có thể đặt giá trị ban đầu mong muốn với:

form.initial['fieldname'] = 'mydesiredvalue'

Tuy nhiên, điều đó sẽ không thay đổi hình thức của widget.

Cách tốt nhất / "django-y" / ít "hacky" nhất để biến lĩnh vực này thành một <input type="hidden">lĩnh vực là gì?

Câu trả lời:


169

Nếu bạn có một mẫu tùy chỉnh và xem, bạn có thể loại trừ trường và sử dụng {{ modelform.instance.field }}để lấy giá trị.

ngoài ra bạn có thể thích sử dụng trong chế độ xem:

form.fields['field_name'].widget = forms.HiddenInput()

nhưng tôi không chắc nó sẽ bảo vệ phương thức lưu trên bài viết.

Hy vọng nó giúp.


1
Tôi kết thúc với một &quot;&quot; is not a valid value for a primary key.phương thức is_valid sau khi sử dụng giải pháp này.
Jens Timmerman

Nó có vẻ lạ. Tôi nghĩ nó liên quan đến thứ khác, bạn có đang hiển thị dưới dạng HiddenInput khóa chính của các đối tượng bạn đang tạo không? Nếu có, bạn không nên.
christophe31

Có thể điều này không cần phải nói, nhưng bạn sẽ cần nhập biểu mẫu trước khi điều này sẽ hoạt động. from django import forms
teewuane

2
trên 1.7 sử dụng cú pháp này: hidden_field_name = forms.CharField(label='reset', max_length=256, widget=forms.HiddenInput())trong đó khóa là cú pháp widget mới hơn ở cuối. Tinh chỉnh cho nhu cầu của bạn.
Marc

195

Điều này cũng có thể hữu ích: {{ form.field.as_hidden }}


3
Đây là câu trả lời tốt nhất IMHO. Tôi luôn ghét sử dụng mã Python "điều khiển" của mình để xác định hiển thị trường biểu mẫu.
trpt4him

Tôi thường làm mẫu biểu mẫu chung với giòn. Nếu bạn sử dụng crispyforms hoặc bạn hiển thị các trường trong một forloop đơn giản vì bạn muốn cấu trúc biểu mẫu của mình trong lớp biểu mẫu của bạn, thì widget ghi đè trong biểu mẫu là cách tốt để làm điều đó. Bu nếu bạn quản lý kết xuất biểu mẫu của bạn vào mẫu của bạn, thực sự, giải pháp này rõ ràng / rõ ràng hơn nhiều.
christophe31

Điều đáng chú ý là điều này dường như xóa bất kỳ lớp nào bạn đã áp dụng cho lĩnh vực này trước đó ...
John Aaron

59

một tùy chọn phù hợp với tôi, xác định trường ở dạng ban đầu là:

forms.CharField(widget = forms.HiddenInput(), required = False)

sau đó khi bạn ghi đè lên nó trong Class mới, nó sẽ giữ nguyên vị trí của nó.


45

Đầu tiên, nếu bạn không muốn người dùng sửa đổi dữ liệu, thì có vẻ như đơn giản hơn để loại trừ trường. Bao gồm nó như một trường ẩn chỉ cần thêm nhiều dữ liệu để gửi qua dây và mời người dùng độc hại sửa đổi nó khi bạn không muốn. Nếu bạn có một lý do chính đáng để bao gồm trường nhưng ẩn nó, bạn có thể chuyển một từ khóa arg cho hàm tạo của modelform. Một cái gì đó như thế này có lẽ:

class MyModelForm(forms.ModelForm):
    class Meta:
        model = MyModel
    def __init__(self, *args, **kwargs):
        from django.forms.widgets import HiddenInput
        hide_condition = kwargs.pop('hide_condition',None)
        super(MyModelForm, self).__init__(*args, **kwargs)
        if hide_condition:
            self.fields['fieldname'].widget = HiddenInput()
            # or alternately:  del self.fields['fieldname']  to remove it from the form altogether.

Sau đó, theo quan điểm của bạn:

form = MyModelForm(hide_condition=True)

Tôi thích cách tiếp cận này để sửa đổi phần bên trong của mô hình theo quan điểm, nhưng đó là vấn đề của hương vị.


11
chỉ là mẹo đơn giản, kwargs.pop ('hide_condition', Sai) thay vì kwargs ['hide_condition']. bạn sẽ xử lý trường hợp không có đối số, có mặc định và del cùng một lúc.
christophe31

2
cảm ơn vì tiền boa, christophe31. Tôi đã cập nhật với đề xuất của bạn, vì nó làm cho mã rõ ràng hơn nhiều.
rych

1
Có thể ẩn trường với phương pháp này hoàn toàn? Giống như nếu bạn đặt trên class Meta: exclude = ["fieldname"]. Vấn đề ở đây là, cách tiếp cận Meta là "tĩnh", nhưng tôi cần một cái gì đó năng động. Xem stackoverflow.com/questions/20243735/
Mạnh

Bạn cab di def __init __ (self, hide_condition = True, * args, ** kwargs) là cách sạch nhất ...
Visgean Sk Bacheloru

22

Đối với dạng bình thường bạn có thể làm

class MyModelForm(forms.ModelForm):
    slug = forms.CharField(widget=forms.HiddenInput())

Nếu bạn có mẫu mô hình, bạn có thể làm như sau

class MyModelForm(forms.ModelForm):
    class Meta:
        model = TagStatus
        fields = ('slug', 'ext')
        widgets = {'slug': forms.HiddenInput()}

Bạn cũng có thể ghi đè __init__phương thức

class Myform(forms.Form):
    def __init__(self, *args, **kwargs):
        super(Myform, self).__init__(*args, **kwargs)
        self.fields['slug'].widget = forms.HiddenInput()

1

Nếu bạn muốn trường luôn bị ẩn, hãy sử dụng như sau:

class MyForm(forms.Form):
    hidden_input = forms.CharField(widget=forms.HiddenInput(), initial="value")

0

Bạn chỉ có thể sử dụng css:

#id_fieldname, label[for="id_fieldname"] {
  position: absolute;
  display: none
}

Điều này sẽ làm cho lĩnh vực và nhãn của nó vô hình.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.