How do I enforce unique user names in Flask?

Wil*_*iam 0 python sql web-applications flask

I'm a complete beginner to Flask and I'm starting to play around with making web apps.

I have a hard figuring out how to enforce unique user names. I'm thinking about how to do this in SQL, maybe with something like user_name text unique on conflict fail, but then how to I catch the error back in Python?

Alternatively, is there a way to manage this that's built in to Flask?

cwa*_*ole 5

这完全取决于您的数据库层.虽然推荐使用SQL Alchemy,但Flask特别没有与特定的ORM系统捆绑在一起.好消息是SQL Alchemy有一个独特的约束.

以下是它的工作原理:

from sqlalchemy.ext.declarative import declarative_base, InvalidRequestError
engine = #my engine
session = Session() # created by sessionmaker(bind=engine)
Base = declarative_base()

class User(Base):
    __tablename__ = 'users'
    id = Column(Integer, primary_key=True)
    name = Column(String, unique=True)

# then later...

user = User()
user.name = 'Frank'
session.add(user)

try:
    session.commit()
    print 'welcome to the club Frank'
except InvalidRequestError:
    print 'You are not Frank. Impostor!!!'
Run Code Online (Sandbox Code Playgroud)

在"之后"两次之后运行零件.你第一次收到欢迎信息,第二次你不会.


附录:Flask与默认身份验证框架 最接近的地方只是将用户存储在dict用户名中.检查以强制执行唯一性的方法是通过手动测试,例如.

if username in digest_db:
    raise Exception('HEY! "{}" already exists! \
                     You can\'t do that'.format(username))
digest_db.add_user(username, password)
Run Code Online (Sandbox Code Playgroud)

或覆盖RealmDigestDB以确保在添加之前检查:

class FlaskRealmDigestDB(authdigest.RealmDigestDB):
    def add_user(self, user, password):
        if user in self:
            raise AttributeError('HEY! "{}" already exists! \
                                  You can\'t do that'.format(user))
        super(FlaskRealmDigestDB, self).add_user(user, password)

    def requires_auth(self, f):
        # yada yada
Run Code Online (Sandbox Code Playgroud)

或覆盖RealmDigestDB,并使其返回不允许重复分配的内容.例如.

class ClosedDict(dict):
    def __setitem__(self, name, val):
       if name in self and val != self[name]:
          raise AttributeError('Cannot reassign {} to {}'.format(name, val))
    super(ClosedDict, self).__setitem__(name,val)


class FlaskRealmDigestDB(authdigest.RealmDigestDB):
    def newDB():
        return ClosedDict()

    def requires_auth(self, f):
        # yada yada
Run Code Online (Sandbox Code Playgroud)

我把它放在这里作为附录,因为该类不会以任何方式保留数据,如果你计划扩展authdigest.RealmDigestDB,你应该使用类似SQLAlchemy的东西,如上所述.