Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
1
Help us understand the problem. What is going on with this article?
@myname6c7c2

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

More than 1 year has passed since last update.

環境

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

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

参考

1
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
myname6c7c2
東京都 フリーランスエンジニア Python+Django C# ASP.NET Vue.js Typescript javascript HTML CSS

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
1
Help us understand the problem. What is going on with this article?