LoginSignup
2
0

More than 1 year has passed since last update.

Django検索で姓と名で分けたフィールドをフルネームで検索させたい

Posted at

概要

Djangoで検索ボックスを作っている時に、姓だけで検索、名だけで検索はできるがフルネームで検索したいという気分だったのでやり方を調べてみました。

モデルについては社員が複数人おり、複数のオフィスに属する可能性があるのでmanyToManyで作成しております。

models.py
from django.db import models


class Office(models.Model):
    name = models.CharField("営業所名", max_length=50)
    code = models.CharField("営業所記号", max_length=10, null=True, blank=True)

    def __str__(self):
        return self.name

class Employee(models.Model):
    employeeNo = models.CharField(
        "社員番号",
        null=True,
        blank=True,
        max_length=5,
        unique=True
    )
    lastName = models.CharField("姓", max_length=30)
    firstName = models.CharField("名", max_length=30)
    lastName_furigana = models.CharField("姓フリガナ", max_length=30)
    firstName_furigana = models.CharField("名フリガナ", max_length=30)
    belong_to_office = models.ManyToManyField(Office)
    date_of_employment = models.DateField("入社日", blank=True, null=True)
    date_of_leaving = models.DateField("退社日", blank=True, null=True)
    created_at = models.DateTimeField("作成日", auto_now_add=True)
    updated_at = models.DateTimeField("更新日", auto_now=True)

    def __str__(self):
        return self.lastName + self.firstName
views.py
from django.views.generic import ListView
from django.db.models.functions import Concat
from django.db.models import Q
from .models import Employee, Office

class EmployeeListView(LoginRequiredMixin, ListView):
    model = Employee
    template_name = "manager/employee_list.html"
    paginate_by = 50

    def get_queryset(self):

        q_word = self.request.GET.get('query')

        if q_word:
            # 空白文字を完全に削除する
            q_word = q_word.replace(' ','')
            q_word = q_word.replace(' ','')
            # フルネームフィールドを追加して検索条件に追加
            object_list = Employee.objects.annotate(full_name=Concat('lastName','firstName')).filter(
                Q(lastName__icontains=q_word) |
                Q(firstName__icontains=q_word) |
                Q(lastName_furigana__icontains=q_word) |
                Q(firstName_furigana__icontains=q_word) |
                Q(employeeNo__icontains=q_word) |
                Q(belong_to_office__name__icontains=q_word) |
                Q(belong_to_office__code__icontains=q_word) |
                Q(full_name__icontains=q_word)
            ).order_by('pk').distinct()

        else:
            object_list = Employee.objects.all().order_by('pk')
        return object_list
employee_list.html

      省略
            <div class="col-12 col-lg-6">

                <form action="" method="get">

                    <div class="input-group">

                        <input name="query" class="form-control" type="text" placeholder="検索条件を入力"
                            value="{{ request.GET.query }}" aria-label="Search for..."
                            aria-describedby="btnNavbarSearch" />
                        <button class="btn btn-primary" type="submit"><i class="fas fa-search"></i></button>
                    </div>
                </form>
            </div>

ポイント

ポイントとしてはEmployee.object.annotateでfull_nameというフィールドを新しく追加してその中身に、元々のlastNameフィールドの値とfirstNameのフィールドをConcatを使って結合してから入れている所です。

2
0
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
2
0