在用django使用模板语法加过滤器渲染标题时,经常会出现想要按指定的文字长度显示标题的部分文字,在超出长度后用"..."来表示未完全显示的这样一个效果。
这时我们一般会用到三个过滤器:
truncatechars:按字符数省略,包括后面的"..."三个点。(中文和英文都算一个字符)
truncatewords:按字的个数省略,不包括后面的"..."三个点。(但只能用于英文)
slice:取N个字符,可以用于中文。(中文和英文都算一个字符,与truncatechars差不多,只是没有"..."三个点)
那么这三个过滤器都没有办法来处理英文和中文混排的标题长度不一致的问题。在网上也看到些方法,但我觉得有些难理解。我想利用utf-8编码格式的中文占三个字节这个属性,来区分汉字和其他字符,并通过它来获得标题所占的字节宽度。然后截取想要显示的按汉字宽度来设定的题目所需宽度的标题文字。达到格式化标题英文汉字混排的统一长度省略的效果。
自定义formattitle.py方法
1 """ 2 格式化英文中文混排时出现的前端长度混乱问题。 3 """ 4 5 6 def formula(coded_value, original_value): #获得汉字和英文总共占据的字符宽度。 7 formula_value = (coded_value - original_value) / 2 + original_value 8 return formula_value 9 10 11 def format_title(article_list, size): 12 article_new_list = [] 13 for i in article_list: 14 switch = True 15 get_original = len(i.title) #获得原始标题长度。 16 get_coded = len(i.title.encode('utf-8')) #获得utf-8编码后的标题长度。 17 get_size = formula(get_coded, get_original) / 2 #获得按汉字字符宽度的字符个数。 18 if get_size > size: #判断,如果大于指定的汉字个数(size为汉字字符宽度的字符个数)。 19 k = 18 #初始化标题截断长度 20 byte_size = size*2 #获得汉字字符的总bytes宽度。 21 while switch: 22 title_cut = i.title[0:k] #截取标题 23 original_size = len(title_cut) #获得截取标题的原始长度 24 coded_size = len(title_cut.encode('utf-8')) #获得截取标题的utf-8编码后的标题长度 25 over_size = formula(coded_size, original_size) #获得英文和汉字的总字符宽度。 26 if (over_size > byte_size-3) and (over_size <= byte_size): #判断是否在规定的区间内。 27 title_cut = title_cut + "..." #追加省略号 28 article_new_list.append({'nid': i.nid, 'title': title_cut}) #加入标题对应的id号,以便url路由所用。并以字典的形式加入到列表中。 29 switch = False 30 else: 31 k += 1 32 else: #当原标题长度未超过指定显示宽度时,直接显示标题名。 33 article_new_list.append({'nid': i.nid, 'title': i.title}) 34 return article_new_list
视图views.py中的函数调用
1 def index(request): 2 article_list = Article.objects.all().order_by('-nid')[0:8] #order_by排序方式 负号表示反向,切片设置显示条数 3 article_format_title = formattitle.format_title(article_list, 18) #一个format_title方法解决英文汉字混排的显示长度,格式:formattitle.format_title(标题的queryset集合对象,要渲染时显示的标题长度) 4 return render(request, "index.html", {'format_title': article_format_title})
前端html中的模板语法
1 <ul> 2 {% for new_dic in format_title %} 3 <li><a href="#"><span> </span>{{ new_dic.title }}</a></li> 4 {% endfor %} 5 </ul>