เปลี่ยนฟิลด์ฟอร์ม Django เป็นฟิลด์ที่ซ่อนอยู่


128

ฉันมีรูปแบบ Django ที่มี a RegexFieldซึ่งคล้ายกับช่องป้อนข้อความปกติมาก

ในมุมมองของฉันภายใต้เงื่อนไขบางประการฉันต้องการซ่อนมันจากผู้ใช้และพยายามรักษาแบบฟอร์มให้คล้ายกันมากที่สุด วิธีใดที่ดีที่สุดในการเปลี่ยนสนามนี้ให้กลายเป็นHiddenInputสนาม

ฉันรู้ว่าฉันสามารถตั้งค่าคุณสมบัติในฟิลด์ด้วย:

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

และฉันสามารถตั้งค่าเริ่มต้นที่ต้องการด้วย:

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

อย่างไรก็ตามจะไม่เปลี่ยนรูปแบบของวิดเจ็ต

วิธีใด "django-y" ที่ดีที่สุด / น้อยที่สุด / น้อยที่สุดในการทำให้ช่องนี้เป็น<input type="hidden">ช่อง

คำตอบ:


169

หากคุณมีเทมเพลตและมุมมองแบบกำหนดเองคุณสามารถยกเว้นฟิลด์และใช้{{ modelform.instance.field }}เพื่อรับค่าได้

นอกจากนี้คุณอาจต้องการใช้ในมุมมอง:

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

แต่ฉันไม่แน่ใจว่ามันจะป้องกันวิธีการบันทึกในโพสต์

หวังว่าจะช่วยได้


1
ฉันลงเอยด้วย&quot;&quot; is not a valid value for a primary key.วิธี is_valid หลังจากใช้วิธีนี้
Jens Timmerman

ฟังดูแปลก ๆ ฉันคิดว่ามันเกี่ยวข้องกับอย่างอื่นคุณแสดงเป็น HiddenInput คีย์หลักของวัตถุที่คุณกำลังสร้างหรือไม่? ถ้าใช่คุณไม่ควร
christophe31

อาจจะไปโดยไม่บอก แต่คุณจะต้องนำเข้าแบบฟอร์มก่อนจึงจะใช้งานได้ from django import forms
teewuane

2
บน 1.7 ใช้ไวยากรณ์นี้: hidden_field_name = forms.CharField(label='reset', max_length=256, widget=forms.HiddenInput())โดยที่คีย์คือไวยากรณ์ของวิดเจ็ตที่ใหม่กว่าในตอนท้าย ปรับแต่งตามความต้องการของคุณ
Marc

196

สิ่งนี้อาจมีประโยชน์: {{ form.field.as_hidden }}


3
นี่คือคำตอบที่ดีที่สุดของ IMHO ฉันเกลียดการใช้โค้ด Python "คอนโทรลเลอร์" ของฉันมาโดยตลอดเพื่อกำหนดการแสดงฟิลด์แบบฟอร์ม
trpt4him

ฉันมักจะสร้างเทมเพลตฟอร์มทั่วไปด้วยรูปแบบกรอบ หากคุณใช้ framedforms หรือคุณแสดงฟิลด์ใน forloop แบบง่าย ๆ เพราะคุณต้องการให้โครงสร้างฟอร์มของคุณอยู่ในคลาสฟอร์มวิดเจ็ตที่แทนที่ในฟอร์มเป็นวิธีที่ดีในการดำเนินการ Bu ถ้าคุณจัดการการแสดงผลแบบฟอร์มในเทมเพลตของคุณแน่นอนว่าโซลูชันนี้ชัดเจน / สะอาดกว่ามาก
christophe31

เป็นที่น่าสังเกตว่าสิ่งนี้ดูเหมือนจะลบชั้นเรียนใด ๆ ที่คุณสมัครลงสนามก่อนหน้านี้ ...
John Aaron

59

ตัวเลือกที่ใช้ได้ผลสำหรับฉันกำหนดฟิลด์ในรูปแบบเดิมเป็น:

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

จากนั้นเมื่อคุณลบล้างในชั้นเรียนใหม่มันจะคงตำแหน่งนั้นไว้


45

ประการแรกหากคุณไม่ต้องการให้ผู้ใช้แก้ไขข้อมูลดูเหมือนว่าจะสะอาดกว่าที่จะยกเว้นฟิลด์ การรวมไว้เป็นฟิลด์ที่ซ่อนอยู่เพียงแค่เพิ่มข้อมูลเพิ่มเติมเพื่อส่งผ่านสายและเชิญผู้ใช้ที่เป็นอันตรายให้แก้ไขเมื่อคุณไม่ต้องการ หากคุณมีเหตุผลที่ดีในการรวมเขตข้อมูล แต่ซ่อนไว้คุณสามารถส่งคำสำคัญ arg ไปยังตัวสร้างของแบบจำลองได้ สิ่งนี้อาจจะ:

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.

จากนั้นในมุมมองของคุณ:

form = MyModelForm(hide_condition=True)

ฉันชอบวิธีนี้ในการปรับเปลี่ยนรูปแบบภายในของโมเดลในมุมมอง แต่เป็นเรื่องของรสนิยม


11
คำแนะนำง่ายๆ kwargs.pop ('hide_condition', False) แทน kwargs ['hide_condition'] คุณจะจัดการกับกรณีที่ไม่มีข้อโต้แย้งมีค่าเริ่มต้นและเดลในเวลาเดียวกัน
christophe31

2
ขอบคุณสำหรับคำแนะนำ christophe31 ฉันได้อัปเดตคำแนะนำของคุณแล้วเนื่องจากทำให้โค้ดชัดเจนขึ้นมาก
rych

1
เป็นไปได้ไหมที่จะซ่อนฟิลด์ด้วยวิธีนี้อย่างสมบูรณ์? class Meta: exclude = ["fieldname"]เช่นถ้าคุณตั้งอยู่บน ปัญหาคือ Meta-approach นั้น "คงที่" แต่ฉันต้องการบางอย่างที่เป็นไดนามิก ดูstackoverflow.com/questions/20243735/…
Themerius

คุณ cab di def __init __ (self, hide_condition = True, * args, ** kwargs) ซึ่งเป็นวิธีที่สะอาดที่สุด ...
Visgean Skeloru

22

สำหรับรูปแบบปกติคุณสามารถทำได้

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

หากคุณมีแบบจำลองคุณสามารถทำสิ่งต่อไปนี้ได้

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

คุณยังสามารถแทนที่__init__วิธีการ

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

1

หากคุณต้องการให้ฟิลด์ถูกซ่อนไว้เสมอให้ใช้สิ่งต่อไปนี้:

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

0

คุณสามารถใช้ css:

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

สิ่งนี้จะทำให้มองไม่เห็นฟิลด์และป้ายกำกับ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.