思路:表中新建一个pinyins字段,类型是数组
pinyins = ArrayField(models.CharField(max_length=128), default=list, blank=True)
# 模型里面是数组,但是实际在数据库中存的是字符串
app下面新建一个script文件夹,存放脚本,脚本作用是把数据库已经存在的名称字段转换成拼音存到pinyins
使用pypinyin模块
from pypinyin import lazy_pinyin, Style
from ..models.jobs import (
JobTitle,
)
STYLES = [
Style.NORMAL, # 标准模式 销售-->[xiaoshou]
Style.FIRST_LETTER, # 首字母模式 销售-->[xs]
]
def get_name_pinyin(name):
results = []
for style in STYLES:
rs = lazy_pinyin(name, style=style, errors="default")
results.append("".join(rs))
return list(set(results))
# python mange.py runscript script下面脚本的文件名,不要后缀
def get_aliases_pinyin(aliases):
results = []
for name in aliases:
results += get_name_pinyin(name)
return list(set(results))
def get_pinyins(name, aliases):
return list(set(get_name_pinyin(name) + get_aliases_pinyin(aliases)))
def run():
queryset = JobTitle.objects.all()
for title in queryset:
title.pinyins = get_pinyins(title.name, title.aliases)
title.save()
#在views中查询
def query_job_title(self, query, size=5, return_fields=None):
if return_fields is None:
return_fields = ["name"]
qs = self.get_queryset().filter(
(
Q(name__icontains=query)
| Q(aliases__icontains=query)
| Q(pinyins__icontains=query)
)
& Q(job_title_job_open__isnull=False)
& Q(is_official=True)
)
if len(return_fields) == 1:
qs = qs.values_list(*return_fields, flat=True)
else:
qs = qs.values(*return_fields)
qs = qs.distinct()[:size]
return qs
为了保证每次新插入数据都能更新到pinyins字段,需要在model模型中重写save方法
def save(self, *args, **kwargs):
w2p = Words2Pinyin(self.name, self.aliases)
self.pinyins = w2p.get_pinyins()
super().save(*args, **kwargs)
# Words2Pinyin是一个工具类
from pypinyin import lazy_pinyin, Style
class Words2Pinyin:
def __init__(self, name, aliases):
self.STYLES = [
Style.NORMAL, # 标准模式 销售-->[xiaoshou]
Style.FIRST_LETTER, # 首字母模式 销售-->[xs]
]
self.name = name
self.aliases = aliases
def get_name_pinyin(self, name):
results = []
for style in self.STYLES:
s = lazy_pinyin(name, style=style, errors="default")
results.append("".join(s))
return list(set(results))
def get_aliases_pinyin(self, aliases):
results = []
for name in aliases:
results += self.get_name_pinyin(name)
return list(set(results))
def get_pinyins(self):
return list(
set(self.get_name_pinyin(self.name) + self.get_aliases_pinyin(self.aliases))
)