Python 烧瓶上的液塞场

Python 烧瓶上的液塞场,python,flask,slug,Python,Flask,Slug,我想创建一个存储在数据库中的slug字段 我搜索了一下,找到了,但在我的应用程序中集成代码时遇到了问题 这是我的modele.py: from unicodedata import normalize def slugfy(text, encoding=None, permitted_chars='abcdefghijklmnopqrstuvwxyz0123456789-'): if isinstance(text, str): text = text

我想创建一个存储在数据库中的slug字段

我搜索了一下,找到了,但在我的应用程序中集成代码时遇到了问题

这是我的
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)
从Unicode数据导入规范化
def slugfy(文本,编码=无,
允许的字符('abcdefghijklmnopqrstuvwxyz012456789-'):
如果isinstance(文本,str):
text=text.decode(编码或“ascii”)
clean_text=text.strip().replace('',-').lower()
而“--”在干净的文本中:
clean_text=clean_text.replace('--','-'))
ascii_text=规范化('NFKD',清除_text)。编码('ascii',忽略')
strict_text=map(λx:x,如果x在允许的字符else'',ascii_text中)
返回“”。加入(严格的文本)
等级(数据库模型):
id=db.Column(db.Integer,主键=True)
nom=db.Column(db.String(200),index=True,unique=True)
slug=db.Column(db.String(255))
chanteurs=db.relationship('Chanson',backref='chanteurs',lazy='dynamic')
定义报告(自我):
返回“”%(self.nom)
定义设置属性(自身、键、值):
超级(唱诗班,自我)。\uuuuu设置属性\uuuuuuuu(键,值)
如果键=='nom':
self.slug=slugfy(self.nom)
等级Chanson(db.型号):
id=db.Column(db.Integer,主键=True)
titre=db.Column(db.String(255))
chanteur_id=db.Column(db.Integer,db.ForeignKey('chanteur.id'))
定义报告(自我):
返回“”%(自身标题)
它不起作用:当我添加一个新的objet(chanteur)时,slug字段是空的

安装名为的包,它使slug化变得轻而易举

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)
从webhelpers.text导入urlify
等级(数据库模型):
id=db.Column(db.Integer,主键=True)
nom=db.Column(db.String(200),index=True,unique=True)
chanteurs=db.relationship('Chanson',backref='chanteur',lazy='dynamic')
定义报告(自我):
返回“”%(self.nom)
@财产
def缓动阀(自):
返回urlify(self.nom)
等级Chanson(db.型号):
id=db.Column(db.Integer,主键=True)
titre=db.Column(db.String(255))
chanteur_id=db.Column(db.Integer,db.ForeignKey('chanteur.id'))
定义报告(自我):
返回“”%(自身标题)
@财产
def缓动阀(自):
返回urlify(self.nom)
有关更多信息,请参阅。

敬礼

如果你想让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方法是从

编辑


在上面的slug函数中,您需要执行循环

clean_text.replace('--', '-')

将其减少到允许的字符后。如果不这样做:
This&That
将作为
This--That
返回,以将slug持久化到数据库中,我使用以下方法(使用非常有用的库):

建议的一个小改进,使用您可以

这将在创建\更新时更新slug的列内容


如果您想要更好的解决方案,您可以按照建议使用@hybrid_property decorator

如果OP想要按slug搜索对象怎么办?谢谢,但您给我的代码没有将slug存储在数据库中,因此如果我更改某个chanson的标题,它也会更改slug,我认为这对我来说不好SEO@MartijnPieters
@classmethod def find_by_slug(cls,slug):返回SomeThing.query.filter(SomeThing.slug==slug.first()
@ajkumar25:但您没有存储slug。@MartijnPieters我认为slug可能是一种方法——如果您需要搜索,您需要另一层间接寻址(即,在url中传递ID)您正在使用哪个orm库?您是否将sqlalchemy作为db导入?是的,我正在导入sqlalchemy,是的,我正在使用Flask-SQLAlchemy@anouar你的代码正在工作。你能解释一下什么不工作吗?我需要flask管理员添加objet(chanteur),检查这张照片,我第一次测试我像第一次测试一样手动加载了slug,当我进入localhost:5000/第一次测试时,它工作了。在第二次测试中,我写了chanteur的名字,这样slug会自动插入,对吗?但它不工作。
clean_text.replace('--', '-')
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)
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)