Django: Bir formdaki giriş alanlarına rastgele html niteliklerini nasıl eklerim?


102

Şuna benzer bir şablonla oluşturulan bir giriş alanım var:

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

Hangisi şu şekilde oluşturulur:

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

Şimdi autocomplete="off", işlenen girdi öğesine bir öznitelik eklemek istediğimi varsayalım , bunu nasıl yapacağım? Veya onclick="xyz()"veya class="my-special-css-class"?

Yanıtlar:


126

Bu sayfayı kontrol edin

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

2
Tamam teşekkürler. Benim durumumda ModelForm kullanıyorum, bu yüzden form alanlarını açıkça tanımlamıyorum (örn. Class AddressForm (forms.ModelForm): class Meta: model = models.Address) Bu, ModelForm'u kullanamayacağım anlamına mı geliyor yoksa özel bir şey var mı? yapma ihtiyacı?
Kullanıcı


1
@InfinitelyLoopy for init for form, alanı kapmak ve widget niteliklerini değiştirmek için bazı kodlar ekleyebilirsiniz. İşte daha önce 3 alanı değiştirmek için kullandığım bazı alanlar: "" ['resim' içindeki alan_adı için, 'görüntü_ küçük', 'görüntü_mobil']: alan = self.fields.get (alan_adı) field.widget.attrs ['veri- dosya '] =' dosya '`` `
Stuart Axon

4
'Zorunlu' ve 'otomatik odaklama' gibi argümanlar almayan özellikler ne olacak?
Wilhelm Klopp

1
Bu çözüm kötü çünkü endişeler arasında ayrım yok. HTML özellikleri python kodu IMO ile yazılmamalıdır. Mikhail Korobov çözümü üstün.
David D.

116

Reklam için özür dilerim, ancak kısa bir süre önce bu tür görevleri daha da az acı verici hale getiren bir uygulama ( https://github.com/kmike/django-widget-tweaks ) yayınladım, böylece tasarımcılar bunu python koduna dokunmadan yapabilirler:

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

Veya alternatif olarak,

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

3
Güzel uygulama Mike, tam da aradığım şey!
jmagnusson

belgeler ayarlarda yüklü uygulamanıza "widget_tweaks" eklemenizi söylemiyor, bunu belgelere eklemeye değer olabilir.
James Lin

Merhaba James, vurgulu değil ama 'Kurulum' bölümünde INSTALLED_APPS'e 'widget_tweaks' eklemeyle ilgili bir not zaten var.
Mikhail Korobov

@MikhailKorobov bu uygulama için çok teşekkür ederim, bana çok yardımcı oldu! Bu tam aradığım şeydi. ModelForm'dan bir forma ihtiyacım vardı ve bu öznitelikleri her bir alana (40 tanesi) manuel olarak eklemek istemedim, bu yüzden saniyeler içinde aynı sonucu elde etmeyi zarif bir şekilde başardım :) Bu kabul edilen cevap olmalı!
Ljubisa Livac

Böyle bir uygulama yazmayı planlıyordum. Çabalarımı kurtardığın için teşekkürler.
Anuj TBE

32

"ModelForm" kullanıyorsanız:

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

3
İyi! Artık tüm widget'ları açıkça tanımlamanıza gerek yok.
Mikael Lindlöf

21

Cevabında verilen @Artificioo olarak ModelFormkullanma imkanı dışında kullanıyorsanız , __init__bunun için Meta'da bir widgetssözlük var :

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

İlgili belgeler


1
Bunun neden yukarıdaki cevaptan daha az olumlu oy aldığını anlamaya çalışıyorum ... Bazen Django / Python geliştiricilerinin işleri yapmanın daha zor yolunu tercih ettiğini düşünüyorum ...
trpt4him

@ trpt4him init yaklaşımını kullanmak, diğer Formlarda yeniden kullanabileceğiniz bir Mixin veya Temel Sınıf oluşturmak için kullanışlıdır. Bu, orta ve büyük ölçekli bir projede tipiktir. Meta.widgets tek bir Form için harikadır. Yani ikisi de iyi cevaplar.
Akhorus

3

Bu şey için bütün bir uygulamayı kullanmak istemedim. Bunun yerine şu kodu burada buldum 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)

etiketi html dosyasında kullanın

{% 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

Son form görünümü ve oluşturmaDjango formlarında modeller oluşturmak ve güncellemek için yeniden kullanılabilir form şablonları oluşturmaya çalışmak için epeyce gün harcadım. Nesneyi değiştirmek veya oluşturmak için ModelForm kullandığımı unutmayın. Formlarımı biçimlendirmek için de önyükleme kullanıyorum. Geçmişte bazı formlar için django_form_tweaks kullandım, ancak çok fazla şablon bağımlılığı olmadan bazı özelleştirmelere ihtiyacım vardı. Projemde zaten jQuery bulunduğundan, formlarımı biçimlendirmek için özelliklerinden yararlanmaya karar verdim. İşte kod ve herhangi bir biçimde çalışabilir.

#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 Kodu Not: Birçok görünüm oluşturma zorluğunu ortadan kaldırmak için bootstrap4 modunu kullanıyorum. Belki genel CreateView veya UpdateView kullanmak daha iyidir. Bootstrap ve jqQery'yi bağlama

 <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 Kodu bunu $(document).ready(function() { /* ... */});fonksiyona yüklemeyi unutmayın .

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')
  });
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.