【Django】様々なデータベース操作

レコードの並べ替え

レコードの並べ替えは、Managerクラスの「order by」というメソッドで行います。

<モデル>.objects.<all/filterなど>.order_by(項目名)

年齢順に並べ替えてみましょう。
views.pyのindex関数を修正します。
hello/views.py

def index(request):
  data = Contact.objects.all().order_by('age')    #☆
  params = {
    'title': 'Hello',
    'message':'',
    'data': data,
  }
  return render(request, 'hello/index.html', params)

index.htmlも見やすいようにフォーマットを調整します。
hello/templates/hello/index.html

<!doctype html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>hello</title>
</head>
<body class="container">
  <h1 class="display-4 text-primary">
    {{title}}</h1>
  <p>{{message|safe}}</p>
  <table class="table">
    <tr>
      <th>id</th>
      <th>name</th>
      <th>age</th>
      <th>mail</th>
      <th>birthday</th>
    </tr>
  {% for item in data %}
    <tr>
      <td>{{item.id}}</td>
      <td>{{item.name}}</td>
      <td>{{item.age}}</td>
      <td>{{item.mail}}</td>
      <td>{{item.birthday}}</td>
    <tr>
  {% endfor %}
  </table>
</body>
</html>

webブラウザにてアクセスします。
年齢順に並び替えられています。

逆順にする場合は、下記のように定義します。

<モデル>.objects.<all/filterなど>.order_by(項目名).reverse()

hello/views.py

def index(request):
  data = Contact.objects.all().order_by('age').reverse()    #☆
  params = {
    'title': 'Hello',
    'message':'',
    'data': data,
  }
  return render(request, 'hello/index.html', params)

werブラウザにてアクセスします。
年齢が逆順に並び替えられています。

指定した範囲のレコードを取り出す

レコード数が多い場合、一部のデータのみ取り出す必要が出てきます。
allやfilterなどで取り出されるのはQUerySetというクラスのインスタンスです。
このQuerySetでは下記のように取り出す位置を指定することができます。

<QuerySet>[開始位置:終了位置]

それでは実際に位置を指定して取り出してみましょう。
views.pyのfind関数を修正します。
/hello/views.py

def find(request):
  if (request.method == 'POST'):
    msg = 'search result:'
    form = FindForm(request.POST)
    find = request.POST['find']
    list = find.split()
    data = Contact.objects.all()[int(list[0]):int(list[1])]    #☆
  else:
    msg = 'search words...'
    form = FindForm()
    data =Contact.objects.all()
  params = {
    'title': 'Hello',
    'message': msg,
    'form':form,
    'data':data,
  }
  return render(request, 'hello/find.html', params)

find.htmlも見やすいように修正します。
hello/templates/hello/find.html

{% load static %}
<!doctype html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>{{title}}</title>
  <link href="https://cdn.jsdelivr.net/npm/bootstrap/dist/css/bootstrap.css" 
  rel="stylesheet" crossorigin="anonymous">
</head>
<body class="container">
    <h1 class="display-4 text-primary">
      {{title}}</h1>
    <p>{{message|safe}}</p>
    <form action="{% url 'find' %}" method="post">
    {% csrf_token %}
    {{ form.as_p }}
    <tr><th></th><td>
      <input type="submit" value="click"
        class="btn btn-primary mt-2"></td></tr>
    </form>
    <hr>
    <table class="table">
      <tr>
        <th>id</th>
        <th>name</th>
        <th>age</th>
        <th>mail</th>
        <th>birthday</th>
      </tr>
    {% for item in data %}
      <tr>
        <td>{{item.id}}</td>
        <td>{{item.name}}</td>
        <td>{{item.age}}</td>
        <td>{{item.mail}}</td>
        <td>{{item.birthday}}</td>
      <tr>
    {% endfor %}
    </table>
  </body>
</html>

webブラウザにてアクセスします。

開始位置と終了位置をスペースで区切って入力して、「click」をクリックします。
「0 2」

レコード集計とaggregate

多数の数値データなどを扱う場合、保存してある値を取り出すだけでなく、必要なレコードの値を集計処理することもよくあります。これはaggregateというメソッドで集計を行います。

変換=<モデル>.objects.aggregate(関数)

引数に設定する関数には下記の集計関数を用います。

Count(項目名)指定した項目のレコード数を返します
Sum(項目名)指定した項目の合計を計算します
Avg(項目名)指定した項目の平均を計算します
Min(項目名)指定した項目から最小値を返します
Max(項目名)指定した項目から最大値を返します

ではageの集計をしてみましょう。
views.pyのindex関数を下記のように修正します。
/hello/views.py

from django.db.models import Count,Sum,Avg,Min,Max


def index(request):
  data = Contact.objects.all()
  re1 = Contact.objects.aggregate(Count('age'))    #☆
  re2 = Contact.objects.aggregate(Sum('age'))    #☆
  re3 = Contact.objects.aggregate(Avg('age'))    #☆
  re4 = Contact.objects.aggregate(Min('age'))    #☆
  re5 = Contact.objects.aggregate(Max('age'))    #☆
  msg = 'count:' + str(re1['age__count']) \
    + '<br>Sum:' + str(re2['age__sum']) \
    + '<br>Average:' + str(re3['age__avg']) \
    + '<br>Min:' + str(re4['age__min']) \
    + '<br>Max:' + str(re5['age__max'])
  params = {
    'title': 'Hello',
    'message':msg,
    'data': data,
  }
  return render(request, 'hello/index.html', params)

webブラウザにてアクセスします。それぞれ集計されていることが確認できます。

SQLを直接実行する

複雑な検索を行う場合、SQLを使用する必要が出てきます。
これには、Managerクラスのrawというメソッドを使います。

変数=<モデル>.objects.raw(クエリ文)

それでは実際にSQLクエリを実行するサンプルを作ってみましょう。
views.pyのfind関数を修復します。
/hello/views.py

def find(request):
  if (request.method == 'POST'):
    msg = request.POST['find']
    form = FindForm(request.POST)
    sql = 'select * from hello_contact'
    if (msg != ''):
        sql += ' where ' + msg
    data = Contact.objects.raw(sql)
    msg = sql
  else:
    msg = 'search words...'
    form = FindForm()
    data =Contact.objects.all()
  params = {
    'title': 'Hello',
    'message': msg,
    'form':form,
    'data':data,
  }
  return render(request, 'hello/find.html', params)

webブラウザにてアクセスします。allで取得するときと同様のデータが表示されます。

検索条件を追加することも可能です。

この記事は役に立ちましたか?

もし参考になりましたら、下記のボタンで教えてください。

関連記事

コメント

この記事へのコメントはありません。