Django đặt giá trị biểu mẫu mặc định


241

Tôi có một Mô hình như sau:

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()

Tôi cũng có một mẫu mô hình cho mô hình trên như sau:

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

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

Tôi muốn biết làm thế nào để đặt giá trị mặc định cho trường ẩn của bể đó. Đây là chức năng của tôi để hiển thị / lưu biểu mẫu cho đến nay:

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/')

Câu trả lời:


401

Bạn có thể sử dụng ban đầu được giải thích ở đây

Bạn có hai tùy chọn để điền giá trị khi gọi hàm tạo biểu mẫu:

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

hoặc đặt giá trị trong định nghĩa biểu mẫu:

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

Và làm thế nào là biến đó initialđược chuyển đến hình thức thực tế? Trong mô hình biểu mẫu thực tế, chúng ta có phải viết dưới dạng tham số / đối số không?
mgPePe

2
@bharal Thật kỳ diệu. ;-) (Hay đúng hơn, các nhà xây dựng biểu mẫu Django hiểu biến "ban đầu" đặc biệt và lặp qua nội dung của nó mà không cần bạn phải làm gì thêm). Cá nhân, tôi thích chỉ định các giá trị mặc định trong định nghĩa biểu mẫu và chỉ sử dụng cơ chế ban đầu = ... nếu mặc định mong muốn là giá trị động (ví dụ: thứ gì đó được nhập bởi người dùng hoặc dựa trên thông tin đăng nhập, vị trí địa lý, v.v.)
Richard J Foster

66
ban đầu không phải là mặc định. Giá trị ban đầu không áp dụng nếu biểu mẫu đã bị ràng buộc :(.
clime

4
Bình luận ở đây để đề cập đến một usecase khác trong đó giải pháp thông số ban đầu này sẽ giúp ích: Trong khi gửi liên kết đăng ký cho ai đó nếu bạn muốn đăng ký trước email / id hoặc bất kỳ thông tin xác thực nào khác trên biểu mẫu đăng ký thì trong trường hợp đó bạn không thể viết nó vào bản thân mô hình là động của nó chứ không phải bạn cần gọi hàm tạo với tham số ban đầu như được đề cập bởi @ umnik700. Hoạt động tuyệt vời!
Keshav Agrawal

1
@Phlip: Không ghi đè View.get_formđể đặt dữ liệu ban đầu. Bất kỳ CBV nào có FormMixin (về cơ bản là tất cả các CBV tạo hoặc chỉnh sửa dữ liệu) đều có thể sử dụng initialbiến cấp độ lớp (để mặc định không thay đổi) hoặc bạn có thể ghi đè FormMixin.get_initial()để trả về một giá trị ban đầu được truyền cho hàm tạo của biểu mẫu (cho mặc định động .)
GDorn

29

Giải pháp khác: Đặt ban đầu sau khi tạo biểu mẫu:

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

Công việc này cho nhu cầu của tôi, chỉ init một lĩnh vực trong mẫu. cảm ơn bạn.
bl4ckb1rd


11

Tôi đã có giải pháp khác này (tôi đang đăng nó trong trường hợp người khác như tôi đang sử dụng phương pháp sau từ mô hình):

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',

            })
        }

Chữ cái đầu tiên được định nghĩa trên __init__hàm làself.fields['is_active'].initial = False


0

Tôi hy vọng điều này có thể giúp bạn:

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

0

Như đã giải thích trong tài liệu Django , initialthì không default.

  • Các ban đầu giá trị của một lĩnh vực được thiết kế để được hiển thị trong một HTML. Nhưng nếu người dùng xóa giá trị này và cuối cùng gửi lại một giá trị trống cho trường này, initialgiá trị sẽ bị mất. Vì vậy, bạn không có được những gì được mong đợi bởi một hành vi mặc định .

  • Các mặc định hành vi là: giá trị mà quá trình xác nhận sẽ thực hiện nếu datalập luận không chứa bất kỳ giá trị cho lĩnh vực này.

Để thực hiện điều đó, một cách đơn giản là kết hợp initialclean_<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']
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.