我想创建一个存储在数据库中的slug字段。
我进行了搜索,发现http://flask.pocoo.org/snippets/5/,但我在应用中集成代码时出现问题。
这是我的modele.py
:
from unicodedata import normalize
def slugfy(text, encoding=None,
permitted_chars='abcdefghijklmnopqrstuvwxyz0123456789-'):
if isinstance(text, str):
text = text.decode(encoding or 'ascii')
clean_text = text.strip().replace(' ', '-').lower()
while '--' in clean_text:
clean_text = clean_text.replace('--', '-')
ascii_text = normalize('NFKD', clean_text).encode('ascii', 'ignore')
strict_text = map(lambda x: x if x in permitted_chars else '', ascii_text)
return ''.join(strict_text)
class Chanteur(db.Model):
id = db.Column(db.Integer, primary_key = True)
nom = db.Column(db.String(200), index = True, unique = True)
slug = db.Column(db.String(255))
chanteurs = db.relationship('Chanson', backref = 'chanteur', lazy = 'dynamic')
def __repr__(self):
return '<Chanteur %r>' % (self.nom)
def __setattr__(self, key, value):
super(Chanteur, self).__setattr__(key, value)
if key == 'nom':
self.slug = slugfy(self.nom)
class Chanson(db.Model):
id = db.Column(db.Integer, primary_key = True)
titre = db.Column(db.String(255))
chanteur_id = db.Column(db.Integer, db.ForeignKey('chanteur.id'))
def __repr__(self):
return '<Chanson %r>' % (self.titre)
它不起作用:当我添加一个新的objet(chanteur)时,slug字段是空的
答案 0 :(得分:12)
为了在数据库中持久化slug,我使用以下方法(使用非常有用的python-slugify
库):
from slugify import slugify # among other things
class Song(db.Model):
id = db.Column(db.Integer, primary_key = True)
title = db.Column(db.String(255))
slug = db.Column(db.String(255))
def __init__(self, *args, **kwargs):
if not 'slug' in kwargs:
kwargs['slug'] = slugify(kwargs.get('title', ''))
super().__init__(*args, **kwargs)
答案 1 :(得分:2)
对@berislav-lopac建议的一个小改进,使用python-slugify你可以
from slugify import slugify
class SlugModel(Base):
name = Column(String)
slug = Column(String)
@staticmethod
def slugify(target, value, oldvalue, initiator):
if value and (not target.slug or value != oldvalue):
target.slug = slugify(value)
event.listen(SlugModel.name, 'set', SlugModel.slugify, retval=False)
这将在create \ update
上更新slug的列内容如果您想要更好的解决方案,可以按建议使用@hybrid_property装饰器here
答案 2 :(得分:1)
安装一个名为Webhelpers的软件包,它可以让slugification成为一块蛋糕。
from webhelpers.text import urlify
class Chanteur(db.Model):
id = db.Column(db.Integer, primary_key=True)
nom = db.Column(db.String(200), index=True, unique=True)
chanteurs = db.relationship('Chanson', backref='chanteur', lazy='dynamic')
def __repr__(self):
return '<Chanteur %r>' % (self.nom)
@property
def slug(self):
return urlify(self.nom)
class Chanson(db.Model):
id = db.Column(db.Integer, primary_key=True)
titre = db.Column(db.String(255))
chanteur_id = db.Column(db.Integer, db.ForeignKey('chanteur.id'))
def __repr__(self):
return '<Chanson %r>' % (self.titre)
@property
def slug(self):
return urlify(self.nom)
有关详细信息,请参阅docs。
答案 3 :(得分:0)
敬礼,
如果你想要slug字段代表le titre de la Chanson,你可以这样做。
from unicodedata import normalize
def slug(text, encoding=None,
permitted_chars='abcdefghijklmnopqrstuvwxyz0123456789-'):
if isinstance(text, str):
text = text.decode(encoding or 'ascii')
clean_text = text.strip().replace(' ', '-').lower()
while '--' in clean_text:
clean_text = clean_text.replace('--', '-')
ascii_text = normalize('NFKD', clean_text).encode('ascii', 'ignore')
strict_text = map(lambda x: x if x in permitted_chars else '', ascii_text)
return ''.join(strict_text)
class Chanson(object):
titre = ''
slugfield = ''
def __setattr__(self, key, value):
super(Chanson, self).__setattr__(key, value)
if key == 'titre':
self.slugfield = slug(self.titre)
m = Chanson()
m.titre = 'Non, je ne regrette rien'
print m.titre
print m.slugfield
slug方法是从here
抓取的被修改
def slug(text):
#slugfy logic here
class Chanson(db.Model):
id = db.Column(db.Integer, primary_key = True)
titre = db.Column(db.String(255))
chanteur_id = db.Column(db.Integer, db.ForeignKey('chanteur.id'))
slugfield = db.Column(db.String(255))
def __setattr__(self, key, value):
super(Chanson, self).__setattr__(key, value)
if key == 'titre':
self.slugfield = slug(self.titre)
答案 4 :(得分:-2)
在上面的slug函数中,你需要进行循环
clean_text.replace('--', '-')
将其缩小为允许的字符后。如果您不这样做:This & That
将作为this--that
返回。