Django ตั้งค่าแบบฟอร์มเริ่มต้น


241

ฉันมีโมเดลดังนี้:

class TankJournal(models.Model):
    user = models.ForeignKey(User)
    tank = models.ForeignKey(TankProfile)
    ts = models.IntegerField(max_length=15)
    title = models.CharField(max_length=50)
    body = models.TextField()

ฉันยังมีรูปแบบโมเดลสำหรับโมเดลด้านบนดังนี้:

class JournalForm(ModelForm):
    tank = forms.IntegerField(widget=forms.HiddenInput()) 

    class Meta:
        model = TankJournal
        exclude = ('user','ts')

ฉันต้องการทราบวิธีการตั้งค่าเริ่มต้นสำหรับฟิลด์ที่ซ่อนรถถังนั้น นี่คือหน้าที่ของฉันที่จะแสดง / บันทึกฟอร์ม:

def addJournal(request, id=0):
    if not request.user.is_authenticated():
        return HttpResponseRedirect('/')

    # checking if they own the tank
    from django.contrib.auth.models import User
    user = User.objects.get(pk=request.session['id'])

    if request.method == 'POST':
        form = JournalForm(request.POST)
        if form.is_valid():
            obj = form.save(commit=False)

            # setting the user and ts
            from time import time
            obj.ts = int(time())
            obj.user = user

            obj.tank = TankProfile.objects.get(pk=form.cleaned_data['tank_id'])

            # saving the test
            obj.save()

    else:
        form = JournalForm()

    try:
        tank = TankProfile.objects.get(user=user, id=id)
    except TankProfile.DoesNotExist:
        return HttpResponseRedirect('/error/')

คำตอบ:


402

คุณสามารถใช้ชื่อเริ่มต้นซึ่งอธิบายไว้ที่นี่

คุณมีสองตัวเลือกในการเติมค่าเมื่อเรียก form constructor:

form = JournalForm(initial={'tank': 123})

หรือตั้งค่าในการกำหนดฟอร์ม:

tank = forms.IntegerField(widget=forms.HiddenInput(), initial=123) 

และตัวแปรนั้นinitialถูกส่งผ่านไปยังแบบฟอร์มจริงอย่างไร ในแบบจำลองที่เกิดขึ้นจริงเราต้องเขียนเป็นพารามิเตอร์ / อาร์กิวเมนต์หรือไม่
mgPePe

2
@bharal มันวิเศษ ;-) (หรือมากกว่านั้นตัวสร้างรูปแบบ Django เข้าใจตัวแปร "เริ่มต้น" พิเศษและวนซ้ำผ่านเนื้อหาโดยไม่จำเป็นต้องทำอะไรเพิ่มเติม) โดยส่วนตัวแล้วฉันต้องการระบุค่าเริ่มต้นในการกำหนดรูปแบบและใช้กลไก initial = ... เท่านั้นหากค่าเริ่มต้นที่ต้องการคือค่าแบบไดนามิก (เช่นสิ่งที่ป้อนโดยผู้ใช้หรือขึ้นอยู่กับการเข้าสู่ระบบที่ตั้งทางภูมิศาสตร์ ฯลฯ )
Richard J Foster

66
initial ไม่ใช่ค่าเริ่มต้น ค่าเริ่มต้นจะใช้ไม่ได้ถ้าแบบฟอร์มถูกผูกไว้ :(.
clime

4
การแสดงความคิดเห็นที่นี่เพื่อพูดถึง usecase อื่นซึ่งโซลูชันของ param เริ่มต้นนี้จะช่วย: ในขณะที่ส่งลิงค์การลงทะเบียนไปยังใครบางคนหากคุณต้องการเติมอีเมล์ / รหัสประจำตัวหรือข้อมูลประจำตัวอื่น ๆ ในแบบฟอร์มการลงทะเบียน โมเดลนั้นเป็นแบบไดนามิก แต่คุณต้องเรียกนวกรรมิกด้วยพารามิเตอร์เริ่มต้นตามที่ระบุไว้โดย @ umnik700 ใช้งานได้ดี!
Keshav Agrawal

1
@Phlip: อย่าแทนที่View.get_formเพื่อตั้งค่าข้อมูลเริ่มต้น CBV ใด ๆ ที่มี FormMixin (โดยทั่วไป CBVs ทั้งหมดที่สร้างหรือแก้ไขข้อมูล) สามารถใช้initialตัวแปรระดับระดับ(สำหรับค่าเริ่มต้นที่ไม่มีการเปลี่ยนแปลง) หรือคุณสามารถแทนที่FormMixin.get_initial()เพื่อคืนค่า dict ของค่าเริ่มต้นที่จะส่งผ่านไปยังตัวสร้างของแบบฟอร์ม .)
GDorn

29

โซลูชันอื่น ๆ : ตั้งค่าเริ่มต้นหลังจากสร้างแบบฟอร์ม:

form.fields['tank'].initial = 123

ใช้ได้ผลกับความต้องการของฉันเพียงเริ่มต้นหนึ่งฟิลด์ในแบบฟอร์ม ขอบคุณ.
bl4ckb1rd

15

หากคุณกำลังสร้าง modelform จากค่า POST เริ่มต้นสามารถกำหนดด้วยวิธีนี้:

form = SomeModelForm(request.POST, initial={"option": "10"})

https://docs.djangoproject.com/en/1.10/topics/forms/modelforms/#providing-initial-values


6
นั่นor Noneเป็นส่วนหนึ่งที่เป็นจริงที่ไม่จำเป็นต้องใช้
smido

11

ฉันมีวิธีแก้ไขปัญหาอื่น (ฉันโพสต์ไว้ในกรณีที่คนอื่นที่ใช้วิธีต่อไปนี้จากโมเดล):

class onlyUserIsActiveField(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(onlyUserIsActiveField, self).__init__(*args, **kwargs)
        self.fields['is_active'].initial = False

    class Meta:
        model = User
        fields = ['is_active']
        labels = {'is_active': 'Is Active'}
        widgets = {
            'is_active': forms.CheckboxInput( attrs={
                            'class':          'form-control bootstrap-switch',
                            'data-size':      'mini',
                            'data-on-color':  'success',
                            'data-on-text':   'Active',
                            'data-off-color': 'danger',
                            'data-off-text':  'Inactive',
                            'name':           'is_active',

            })
        }

เริ่มต้นจะถูกกำหนดใน__init__ฟังก์ชั่นเป็นself.fields['is_active'].initial = False


0

ฉันหวังว่านี่จะช่วยคุณได้:

form.instance.updatedby = form.cleaned_data['updatedby'] = request.user.id

0

ตามที่อธิบายไว้ในเอกสาร Django , ไม่ได้initialdefault

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

  • เริ่มต้นพฤติกรรมคือมูลค่าที่กระบวนการตรวจสอบจะใช้เวลาถ้าdataอาร์กิวเมนต์ไม่ได้มีค่าใด ๆ สำหรับฟิลด์

ในการดำเนินการนั้นวิธีที่ตรงไปตรงมาคือการรวมinitialและclean_<field>():

class JournalForm(ModelForm):
    tank = forms.IntegerField(widget=forms.HiddenInput(), initial=123) 

    (...)

    def clean_tank(self):
        if not self['tank'].html_name in self.data:
            return self.fields['tank'].initial
        return self.cleaned_data['tank']
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.