7
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でIN演算子を使ったクエリを生成する方法

Last updated at Posted at 2016-11-23

Django:1.10

結論から言うと、以下に記載されていました。

QuerySet API reference | Django documentation | Django
https://docs.djangoproject.com/ja/1.10/ref/models/querysets/#in

クエリに関しては、このページを見たらよさそう。

例えば、選択した著者の出版した本一覧を取得するクエリを生成する場合は、以下のように書きます。

views.py
def search(request):

    form = SearchForm(request.POST)

    books = None

    if form.is_valid():
        books = Book.objects.filter(author_id__in = form.cleaned_data['author'])

    return render(request, 'books/search.html', {'form': form, 'books': books})

著者、本、ジャンルのモデル。

models.py
from django.db import models

class Author(models.Model):
    name = models.CharField(max_length=128)

    def __str__(self):
        return self.name

class Genre(models.Model):
    name = models.CharField(max_length=128)

    def __str__(self):
        return self.name

class Book(models.Model):
    name = models.CharField(max_length=512)
    author =  models.ForeignKey(Author, on_delete=models.CASCADE)
    genres = models.ManyToManyField(Genre)

    def __str__(self):
        return self.name

著者を選択するフォーム。

forms.py
from django import forms

from books.models import Author

class SearchForm(forms.Form):

    authors = [(author.id, author.name) for author in Author.objects.all()]

    author = forms.MultipleChoiceField(label='著者', widget=forms.CheckboxSelectMultiple,
            choices=authors, required=False)

テンプレートは以下のようにすると、

searth.html
<form method="post" action="">
    {% csrf_token %}
    <h1>{{ form.author.label }}</h1>
    {{ form.author }}
    <input type="submit" value="検索" />
    <hr />
    <table border="1">
        <tr>
            <th>タイトル</th>
            <th>著者</th>
            <th>ジャンル</th>
        </tr>
        {% for b in books %}
            <tr>
                <td>{{ b.name }}</td>
                <td>{{ b.author.name }}</td>
                <td>{% for g in b.genres.all %}{{ g.name }}{% endfor %}</td>
            </tr>
        {% endfor %}
    </table>
</form>

こんな感じで表示されます。

無題.png


追記 2016/11/26

著者追加を実装していたのですが、1点問題がでてきました。
上記のforms.pyで著者を選択するためにauthorsをテーブルから取得していますが、この方法ではアプリケーションスコープになるらしく、著者を追加してもサーバ再起動しないと画面に反映されません。
トランザクションデータをchoicesに代入する場合はどうするべきか、別途考えます。

追記 2017/01/05

上記問題を解決しました。

DjangoのMultipleChoiceFieldでchoicesが更新されない
http://qiita.com/nakkun/items/26598a7bf1f80b215ff2

多分、これで大丈夫なはず。。。

7
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
7
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?