多くのさまざまなデータが動的にレンダリングされる複雑な詳細ビューがあります。私のモデルには何百ものフィールドがあり、その多くは互いに関連しています。クエリを実行するために、これらのフィールドの数をグループ化できるようにしたいと考えています。これを行う方法はありますか?
特定のフィールドを厳選してグループ化するために、私の現在のアプローチは、各グループに共通のフィールド名に単語拡張子を使用することです。たとえば、次のようなフィールド名です。
ampicillin = models.CharField(...)
ciprofloxacin = models.CharField(...)
...
なる:
ampicillin_antimicro = models.CharField(...)
ciprofloxacin_antimicro = models.CharField(...)
...
次に、フィールド名リストを作成し、部分文字列検索を使用して特定のフィールド グループにアクセスします。どうすればいいですか?以下は、これまでの私の試みと問題の要約です。
_meta の使用
_meta を使用して生のモデル フィールド名情報にアクセスできます。
all_fields = []
for field in MyModel._meta.fields:
all_fields.append(field)
これにより、次のようなリストが得られます。
[<django.db.models.fields.CharField: ampicillin_antimicro>,
<django.db.models.fields.CharField: ciprofloxacin_antimicro>, ...]
しかし、これから必要な情報を抽出する方法を理解できませんでした。
_meta と field.get_attname_column()[0] の使用
フィールド名オブジェクトのリストを文字列として作成できます。
field_names = []
for field in MyModel._meta.fields:
newfield = field.get_attname_column()[0]
field_names.append(newfield)
これにより、field_names の追加リストが得られます。
['ampicillin_antimicro', 'ciprofloxacin_antimicro', ...]
部分文字列検索を追加すると、必要なフィールド名のサブセットを取得できます。たとえば、検索文字列「antimic」を使用すると、次のようになります。
field_names = []
search_string = "antimic"
for field in Bacteria._meta.fields:
newfield = field.get_attname_column()[0]
if search_string in newfield:
field_names.append(newfield)
「グループ ワード拡張子」を含むフィールド名を正常に分離します。フィールド名の実際の値にアクセスできなくなったことを除けば、すべて問題ありません。フィールド名自体だけです。リストがテンプレートで繰り返されると、フィールド名のみが返されます。
<li>
{% if field_names %}
<i style="color: blue"><b>A</b>ntibiotic tolerance:</i>
{% for f in field_names %}
{{f|default_if_none:''}}
{% endfor %}
{% endif %}
</li>
タプルと辞書の使用
リストを tuplify して dictify し、結果の辞書を使用しようとすると:
field_names = []
field_names_dict = dict(zip(field_names, field_names))
field_names_tuple = tuple(field_names_dict)
for key, val in field_names_tuple.items():
if val is not None:
field_names.append(val)
値ではなく、結果として名前を取得します。
ハードコーディングされた辞書
これまでのところ、機能する唯一の方法は、詳細ビューでクエリごとに特定の辞書をハードコーディングすることです。
model = Model.objects.all()
antibiotics = []
antibiotics_dict = {'amp': model.ampicillin_antimicro,
'cipro': model.ciprofloxacin_antimicro, ...}
for key, val in antibiotics_dict.items():
if val is not None:
antibiotics.append(val)
これは問題なく機能しますが、辞書が大きくなると複雑になり、キーと値のペアをハードコーディングするという考えは好きではありません。私は解決策に非常に近づいているように感じますが、コーディングの初心者であるため、明らかに何かが欠けています。誰か助けてくれませんか?乾杯。
シェルビントンのソリューション
Mr. Shelvington の提案に従って、コードを次のように変更しました。
search_string = "antimic"
field_names = [f.name for f in Bacteria._meta.get_fields()
if search_string in f.name]
prelist = get_object_or_404(Bacteria.objects.values(*field_names), slug=slug)
for key, val in prelist.items():
if val is not None:
antibiotics = prelist
2 つの変数 (部分文字列と「抗生物質」) しかないことに注意してください。このコードは、追加の部分文字列と辞書の作成に再利用できます。次に、テンプレートを次のように変更しました。
<li>
{% if antibiotics %}
<i style="color: blue"><b>A</b>ntibiotic tolerance:</i>
{% for key, val in antibiotics.items %}
{{ val }}
{% endfor %}
{% endif %}
</li>
追加メモ: ビュー内の辞書を繰り返し処理して、繰り返しの値が見つからない場合に HTML テキスト タイトルが消えるようにしました。