4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Django の ModelChoiceField で option タグに属性を追加したい

Last updated at Posted at 2019-10-21

環境

django 2.2
python 3.6.8

やりたい事

forms.Select の option タグに value 以外の属性も追加したい。

これを

<select name="persons" required="" id="id_persons">
  <option value="" selected="">---------</option>
  <option value="1">山田 太郎</option>
  <option value="2">山田 花子</option>
</select>

↓みたいにしたい

<select name="persons" required="" id="id_persons">
  <option value="" selected="">---------</option>
  <option value="1" age="10">山田 太郎</option>
  <option value="2" age="20">山田 花子</option>
</select>

やってみた

modelsの定義はこんな感じ

models.py
class Person(models.Model):
    first_name = models.CharField(max_length=20)
    last_name = models.CharField(max_length=20)
    age = models.IntegerField()

    def __str__(self):
        return f"{self.last_name} {self.first_name}" 

forms.Select を継承した SelectPersonWidget を作成

custom_widget.py
class SelectPersonWidget(forms.Select):

__init__ で queryset を渡しておく

custom_widget.py
class SelectPersonWidget(forms.Select):
    def __init__(self, attrs=None, choices=(), queryset=None):
        self.queryset = queryset
        super().__init__(attrs, choices)

create_option で queryset から必要な情報を取得して attrs に追加する

custom_widget.py
class SelectPersonWidget(forms.Select):
    def __init__(self, queryset, attrs=None, choices=()):
        self.queryset = queryset
        super().__init__(attrs, choices)

    def create_option(self, name, value, label, selected, index, subindex=None, attrs=None):
        option = super().create_option(name, value, label, selected, index, subindex, attrs)
        if value:
            person = self.queryset.get(pk=value)
            option['attrs'].update({'age': person.age}) # ここで attrs に追加
        return option

作成した SelectPersonWidget を ModelChoiceField の widget に指定する

forms.py
from django. import forms

from .models import Person
from .custom_widget import SelectPersonWidget


class SampleForm(forms.Form):
    all_person = Person.objects.all()
    
    persons = forms.ModelChoiceField(
        queryset=all_person,
        widget=SelectPersonWidget(queryset=all_person) # ここで指定する
    )

描画してみる。
option タグに age属性 が追加された

image.png

他に方法があれば知りたい

参考

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?