スキップしてメイン コンテンツに移動

投稿

12月, 2021の投稿を表示しています

Django: extra_viewsのInlineFormSetFactoryにてdatalistをサブフォーム側で表示

前回はInlineFormSetFactoryにてサブフォーム側にchoicesをつかって、静的に入力補助できるようにした のですが、さらに動的に入力補助できないものかと思い、datalistを使えないかとやってみたところ動いたので、備忘録として挙げてみることにしました。 なお、html5のdatalist自体の説明は割愛します。 まず、サブフォーム側です。以下のようにしました。 class art_imageForm(InlineFormSetFactory): model = art_image fields = ['art_image_title', 'original_img', ] factory_kwargs = { 'widgets' : {\ 'art_image_title':\ forms.TextInput( attrs={'list': 'art_image_titles', 'placeholder': 'enter image title'}, ), }, } ここでは、datalistをid="art_image_titles"のものから参照するということと、placeholderをここで指定しています。つづいて、テンプレート側です。フィールドを表示する部分だけですが、以下のようにしました。 {% for form in formset %} {% for field in form %} <tr> <th class="bg-light"> {% if field.field.widget.is_hidden %} {% else %}

Django extra_views の InlineFormSetFactoryをつかい、dropdown listboxを表示させる

複数の子テーブルが紐づいた詳細編集フォームに、python3-django-extra-views をつかうことで非常に簡単にサブフォームとの連携ができます。しかし、データベースのテーブルを使いまわすため、models.pyでchoicesを指定すると、とある編集場面では問題はないが、ほかの編集場面では異なったchoicesを表示させたい場合がありました。 そこで、いろいろと探してみたのですが、extra_viewsを使ってインラインサブフォーム側でchoicesを指定するのに、これだという記事はみあたりません。ただ、ヒントになる記事はあり、factory_kwargsを指定してフィールドウィジットに細工をすればよさそうだったので、いろいろと試したところできたので、忘備録として挙げてみることにしました。 具体的にいうと、PCパーツのデータベースを作成しようとしているのですが、list表示は無論、たとえばマザーボードの詳細編集フォームとメモリーの詳細編集フォームを分ける必要があります。(マザーボードとメモリーでは属性が異なるためです。たとえば、マザーボードとメモリーには、ベンダー名はあっても、拡張スロットやUSBはメモリーにはありませんし、逆にメモリーの一枚、二枚組の属性はマザーボードにはありません。) そこで、表題のように、InlineFomrSetFactoryを使いつつも、モデル側ではなく、form側でdropdown listboxのchoicesを個別に指定する必要がある、ということです。前置きが長くなりましたが、コード自体は非常にシンプルです。以下はマザーボードの詳細を入力するためのインラインサブフォームの例です。 class art_propForm(InlineFormSetFactory): model = art_prop fields = ('prop_cat', 'prop_name', 'prop_dsc1', 'prop_dsc2', 'prop_dsc3', 'prop_dsc4', 'prop_dsc5', ) PROP_CAT_CHOICES = ( ("&quo

MariaDBでSelect Distinctした結果の各行に連番を振る

今回も備忘録としてあげますが、表題の通りにしたいが以下の様にすると、連番を含めてselect distinctするため、期待通りに動いてくれません。 SELECT prop_dsc1, row_number() OVER (PARTITION BY prop_dsc1 ORDER BY prop_dsc1) venodr_no FROM art_prop WHERE prop_name="vendor"; +-----------+-----------+ | prop_dsc1 | venodr_no | +-----------+-----------+ | ASRock | 1 | | ASRock | 2 | | ASRock | 3 | | ASRock | 4 | | ASRock | 5 | | MSI | 1 | +-----------+-----------+ 6 rows in set (0.000 sec) つまり、select distinctした後に連番をふればいいので、以下の様にします。 SELECT t_vendor.vendor, row_number() OVER (ORDER BY t_vendor.vendor) vendor_no FROM ( SELECT distinct prop_dsc1 AS vendor FROM art_prop WHERE prop_name="vendor" ) as t_vendor; +--------+-----------+ | vendor | vendor_no | +--------+-----------+ | ASRock | 1 | | MSI | 2 | +--------+-----------+ ところで、PARTITION BYですが、PARTITION BY t_vendor.vendorを入れると、これも期待通りにならないので注意が必要です。 SELECT t_vendor.vendor,