Django: ฉันจะเพิ่มแอตทริบิวต์ html ที่กำหนดเองในช่องป้อนข้อมูลในแบบฟอร์มได้อย่างไร


101

ฉันมีช่องป้อนข้อมูลที่แสดงผลด้วยเทมเพลตดังนี้:

<div class="field">
   {{ form.city }}
</div>

ซึ่งแสดงผลเป็น:

<div class="field">
    <input id="id_city" type="text" name="city" maxlength="100" />
</div>

ตอนนี้สมมติว่าฉันต้องการเพิ่มautocomplete="off"แอตทริบิวต์ให้กับองค์ประกอบอินพุตที่แสดงผลฉันจะทำอย่างไร หรือonclick="xyz()"หรือclass="my-special-css-class"?

คำตอบ:


126

ตรวจสอบหน้านี้

city = forms.CharField(widget=forms.TextInput(attrs={'autocomplete':'off'}))

2
โอเคขอบคุณ. ในกรณีของฉันฉันใช้ ModelForm ดังนั้นฉันจึงไม่ได้กำหนดฟิลด์ฟอร์มอย่างชัดเจน (เช่นคลาส AddressForm (ฟอร์ม ModelForm): class Meta: model = models.Address หมายความว่าฉันไม่สามารถใช้ ModelForm ได้หรือมีบางอย่างที่พิเศษฉัน จำเป็นต้องทำ?
ผู้ใช้

1
โอเคไม่เป็นไร rtfm: docs.djangoproject.com/en/dev/topics/forms/modelforms
ผู้ใช้

1
@InfininiteLoopy ภายในinitสำหรับแบบฟอร์มคุณสามารถเพิ่มโค้ดเพื่อคว้าฟิลด์และปรับเปลี่ยนแอ็ตทริบิวต์วิดเจ็ต นี่คือบางส่วนที่ฉันใช้ก่อนหน้านี้เพื่อแก้ไข 3 ฟิลด์: `` สำหรับ field_name ใน ['image', 'image_small', 'image_mobile']: field = self.fields.get (field_name) field.widget.attrs ['data- file '] =' file '``
Stuart Axon

4
แล้วแอตทริบิวต์ที่ไม่ใช้อาร์กิวเมนต์เช่น "required" และ "autofocus" ล่ะ?
Wilhelm Klopp

1
การแก้ปัญหานี้ไม่ดีเนื่องจากไม่มีการแยกความกังวล ไม่ควรเขียนแอตทริบิวต์ HTML ด้วยรหัสหลาม IMO โซลูชัน Mikhail Korobov นั้นเหนือกว่า
David D.

115

ขออภัยสำหรับการโฆษณา แต่ฉันเพิ่งเปิดตัวแอป ( https://github.com/kmike/django-widget-tweaks ) ที่ทำให้งานดังกล่าวเจ็บปวดน้อยลงดังนั้นนักออกแบบจึงสามารถทำได้โดยไม่ต้องแตะรหัส python:

{% load widget_tweaks %}
...
<div class="field">
   {{ form.city|attr:"autocomplete:off"|add_class:"my_css_class" }}
</div>

หรืออีกทางหนึ่งคือ

{% load widget_tweaks %}
...
<div class="field">
   {% render_field form.city autocomplete="off" class+="my_css_class" %}
</div>

3
แอพที่ดี Mike สิ่งที่ฉันกำลังมองหา!
jmagnusson

เอกสารประกอบไม่ได้บอกให้คุณเพิ่ม "widget_tweaks" ลงในแอปที่คุณติดตั้งในการตั้งค่าอาจคุ้มค่าที่จะใส่ลงในเอกสารประกอบ
James Lin

สวัสดีเจมส์ไม่ได้เน้น แต่ในส่วน 'การติดตั้ง' มีหมายเหตุเกี่ยวกับการเพิ่ม 'widget_tweaks' ใน INSTALLED_APPS อยู่แล้ว
Mikhail Korobov

@MikhailKorobov ขอบคุณมากสำหรับแอพนี้มันช่วยฉันได้มาก! นี่เป็นสิ่งที่ถูกต้องที่ฉันกำลังมองหา ฉันต้องการแบบฟอร์มจาก ModelForm และไม่ต้องการแทรกแอตทริบิวต์นี้ลงในทุกๆช่อง (40 ช่องด้วยตนเอง) ดังนั้นฉันจึงจัดการได้อย่างหรูหราเพื่อให้ได้ผลลัพธ์เดียวกันในไม่กี่วินาที :) นี่ควรเป็นคำตอบที่ยอมรับ!
Ljubisa Livac

ฉันวางแผนที่จะเขียนใบสมัครดังกล่าว ขอบคุณที่ช่วยประหยัดความพยายามของฉัน
Anuj TBE

31

หากคุณกำลังใช้ "ModelForm":

class YourModelForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(YourModelForm, self).__init__(*args, **kwargs)
        self.fields['city'].widget.attrs.update({
            'autocomplete': 'off'
        })

3
ดี! ไม่จำเป็นต้องกำหนดวิดเจ็ตทั้งหมดอย่างชัดเจนในตอนนี้
Mikael Lindlöf

20

หากคุณกำลังใช้ModelFormนอกเหนือจากความเป็นไปได้ในการใช้__init__เป็น @Artificioo ที่ระบุไว้ในคำตอบของเขาแล้วยังมีwidgetsพจนานุกรมใน Meta สำหรับเรื่องนั้น:

class AuthorForm(ModelForm):
    class Meta:
        model = Author
        fields = ('name', 'title', 'birth_date')
        widgets = {
            'name': Textarea(attrs={'cols': 80, 'rows': 20}),
        }

เอกสารที่เกี่ยวข้อง


1
พยายามคิดว่าทำไมสิ่งนี้ถึงได้รับคะแนนโหวตน้อยกว่าคำตอบข้างบน ... บางครั้งฉันคิดว่านักพัฒนา Django / Python ก็ชอบวิธีที่ยากกว่าในการทำสิ่งต่างๆ ...
trpt4him

@ trpt4him การใช้วิธีการเริ่มต้นจะมีประโยชน์ในการสร้าง Mixin หรือ Base Class ที่คุณสามารถใช้ซ้ำในฟอร์มอื่นได้ นี่คือ typicall ในโครงการขนาดกลางถึงขนาดใหญ่ Meta.widgets นั้นยอดเยี่ยมสำหรับฟอร์มเดียว ดังนั้นทั้งสองคำตอบที่ดี
Akhorus

3

ฉันไม่ต้องการใช้ทั้งแอปสำหรับสิ่งนี้ แต่ฉันพบรหัสต่อไปนี้ที่นี่https://blog.joeymasip.com/how-to-add-attributes-to-form-widgets-in-django-templates/

# utils.py
from django.template import Library
register = Library()

@register.filter(name='add_attr')
def add_attr(field, css):
    attrs = {}
    definition = css.split(',')

    for d in definition:
        if ':' not in d:
            attrs['class'] = d
        else:
            key, val = d.split(':')
            attrs[key] = val

    return field.as_widget(attrs=attrs)

ใช้แท็กในไฟล์ html

{% load utils %}
{{ form.field_1|add_attr:"class:my_class1 my_class2" }}
{{ form.field_2|add_attr:"class:my_class1 my_class2,autocomplete:off" }}

0

รูปลักษณ์และการแสดงผลแบบฟอร์มสุดท้ายฉันใช้เวลาสองสามวันในการสร้างเทมเพลตฟอร์มที่ใช้ซ้ำได้เพื่อสร้างและอัปเดตโมเดลในรูปแบบ Django โปรดทราบว่ากำลังใช้ ModelForm เพื่อเปลี่ยนแปลงหรือสร้างวัตถุ ฉันกำลังใช้ bootstrap เพื่อจัดรูปแบบฟอร์มของฉัน ฉันเคยใช้ django_form_tweaks สำหรับบางรูปแบบในอดีต แต่ฉันต้องการการปรับแต่งบางอย่างโดยไม่ต้องพึ่งพาเทมเพลตมากนัก เนื่องจากฉันมี jQuery ในโครงการของฉันอยู่แล้วฉันจึงตัดสินใจที่จะใช้ประโยชน์จากคุณสมบัติของมันเพื่อจัดรูปแบบฟอร์มของฉัน นี่คือรหัสและสามารถใช้งานได้กับทุกรูปแบบ

#forms.py
from django import forms
from user.models import User, UserProfile
from .models import Task, Transaction

class AddTransactionForm(forms.ModelForm):
    class Meta:
       model = Transaction
       exclude = ['ref_number',]
       required_css_class = 'required'

Views.py

@method_decorator(login_required, name='dispatch')
class TransactionView(View):
def get(self, *args, **kwargs):
    transactions = Transaction.objects.all()
    form = AddTransactionForm
    template = 'pages/transaction.html'
    context = {
        'active': 'transaction',
        'transactions': transactions,
        'form': form
    }
    return render(self.request, template, context)

def post(self, *args, **kwargs):
    form = AddTransactionForm(self.request.POST or None)
    if form.is_valid():
        form.save()
        messages.success(self.request, 'New Transaction recorded succesfully')
        return redirect('dashboard:transaction')
    messages.error(self.request, 'Fill the form')
    return redirect('dashboard:transaction')

HTML Code Note: กำลังใช้โมดอล bootstrap4 เพื่อขจัดความยุ่งยากในการสร้างมุมมองจำนวนมาก อาจจะดีกว่าถ้าใช้ CreateView หรือ UpdateView ทั่วไป ลิงก์ Bootstrap และ jqQery

 <div class="modal-body">
    <form method="post" class="md-form" action="." enctype="multipart/form-data">
      {% csrf_token %}
      {% for field in form %}
      <div class="row">
        <div class="col-md-12">
          <div class="form-group row">
            <label for="" class="col-sm-4 col-form-label {% if field.field.required %}
            required font-weight-bolder text-danger{%endif %}">{{field.label}}</label>
            <div class="col-sm-8">
              {{field}}
            </div>

          </div>
        </div>
      </div>

      {% endfor %}

      <input type="submit" value="Add Transaction" class="btn btn-primary">
    </form>
  </div>

รหัส Javascriptอย่าลืมโหลดสิ่งนี้ใน$(document).ready(function() { /* ... */});ฟังก์ชัน

var $list = $("#django_form :input[type='text']");
$list.each(function () {
    $(this).addClass('form-control')
  });
  var $select = $("#django_form select");
  $select.each(function () {
    $(this).addClass('custom-select w-90')
  });
  var $list = $("#django_form :input[type='number']");
  $list.each(function () {
    $(this).addClass('form-control')
  });
  var $list = $("form :input[type='text']");
  $list.each(function () {
    $(this).addClass('form-control')
  });
  var $select = $("form select");
  $select.each(function () {
    $(this).addClass('custom-select w-90')
  });
  var $list = $("form :input[type='number']");
  $list.each(function () {
    $(this).addClass('form-control')
  });
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.