日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python中英文字符和中文字符存储长度不同_Django如何正确截取中英混合字符串及表单中限制中文字符中长度...

發布時間:2023/12/1 python 51 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python中英文字符和中文字符存储长度不同_Django如何正确截取中英混合字符串及表单中限制中文字符中长度... 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

中文字符和英文字符所占的字節長度是不一樣,一個是2個字節,一個是1個字節,這給我們用英文的web框架開發中文app帶來了麻煩。比如Django自帶過濾器truncatewords并不支持截取中文,另外模型中CharField中的max_length選項用于限制中英混合字符串的長度基本上是失真的,需要額外自定義表單驗證限制某些字段比如標題的長度。小編我今天就給大家分享幾個例子和解決方案。

我們同樣以博客的Article模型為例,我們試圖限制標題的最大長度為90 個字符。

class Article(models.Model):

"""Article Model"""

title = models.CharField('Title', max_length=90,db_index=True)

90個英文字符也就是10來個單詞,作為標題長度剛好合適。如果中文標題允許長達90個中文字符,這將是個恐怖的存在,也就意味著這里標題的長度限制對于中文或中英混雜字符串等于形同虛設。注意: Django CharField的max_length是按字符數來限制的,而不是字節數。同樣Django的length模板過濾器和python的len函數默認也是統計字符數,而不是字節數。

更好的解決方法?我們統計中英混合字符串的字節數,然后通過表單實現按字節數來限制,代碼如下所示。我們先通過python的encode方法將混合字符串轉化為二進制數據,再使用python的len方法統計字節長度。用該方法“我是a"會被統計成5,而不是3。該方法并不完美,但我們可以實現限制標題長度為90個英文字符或45個中文字符。

class ArticleForm(forms.ModelForm):

class Meta:

model = Article

exclude = ['author', ]

def clean_title(self):

title = self.cleaned_data['title']

if len(title.encode('gb18030')) > 90: # 轉成二進制統計字節 b'\xce\xd2\xca\xc7ab\xd6\xed')

raise forms.ValidationError('The length of title must be shorter than 90 chars.')

return title

另一個例子是我們經常需要根據正文截取文中開頭部分作為摘要,使用Django自帶的模板過濾器truncatechars和truncatewords僅適用于羅馬及英文字符的,但對中文字符串完全不適用,如下所示:

{{ article.body|striptags|truncatewords:20 }}

這是我們需要自定義模板過濾器截取中英混合字符串,網上已有現成可用代碼,我在這里轉貼給大家備用。如果你不知道如何自定義Django模板過濾器及如何使用它們,請強烈閱讀本文Django基礎(16): 模板標簽(tags)的分類及如何自定義模板標簽

from django import template

from django.template.defaultfilters import stringfilter

register = template.Library()

@register.filter

@stringfilter

def cut_str(str, length=10):

"""

截取字符串,使得字符串長度等于length,并在字符串后加上省略號 """

is_encode = False

try:

str_encode = str.encode('gb18030') #b'\xce\xd2\xca\xc7ab\xd6\xed'

is_encode = True

except:

pass

if is_encode:

l = length*2

if l < len(str_encode):

l = l - 3

str_encode = str_encode[:l]

try:

str = str_encode.decode('gb18030') + '...'

except:

str_encode = str_encode[:-1]

try:

str = str_encode.decode('gb18030') + '...'

except:

is_encode = False

if not is_encode:

if length < len(str):

length = length - 2

return str[:length] + '...'

return str

使用時先載入自定義標簽,再按如下使用即可:

{% load your_tags %}

{{ article.body|striptags|cut_str:120 }}

相關閱讀Django基礎(15): 模板過濾器(filter)的工作原理及如何自定義模板過濾器

Django實戰: 利用自定義模板標簽實現仿CSDN博客月度歸檔

Django實戰專題: 開發專業博客(1)之內容管理后臺開發

大江狗 - 微信公眾號【Python Web與Django開發】

2020.2.15

創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的python中英文字符和中文字符存储长度不同_Django如何正确截取中英混合字符串及表单中限制中文字符中长度...的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。