рдореЗрдЧрд╛-рдлреНрд▓рд╛рд╕реНрдХ рдЯреНрдпреВрдЯреЛрд░рд┐рдпрд▓, рднрд╛рдЧ 6: рдкреНрд░реЛрдлрд╛рдЗрд▓ рдкреЗрдЬ рдФрд░ рдЕрд╡рддрд╛рд░

рдпрд╣ рдПрдХ рд╢реНрд░реГрдВрдЦрд▓рд╛ рдореЗрдВ рдЫрдард╛ рд▓реЗрдЦ рд╣реИ рдЬрд╣рд╛рдВ рдореИрдВ рдлреНрд▓рд╛рд╕реНрдХ рдорд╛рдЗрдХреНрд░реЛрдлреНрд░рд╛рдорд╡рд░реНрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдкрд╛рдпрдерди рд╡реЗрдм рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд▓рд┐рдЦрдиреЗ рдХреЗ рдЕрдкрдиреЗ рдЕрдиреБрднрд╡ рдХрд╛ рджрд╕реНрддрд╛рд╡реЗрдЬреАрдХрд░рдг рдХрд░реВрдВрдЧрд╛ред



рдЗрд╕ рдЧрд╛рдЗрдб рдХрд╛ рдЙрджреНрджреЗрд╢реНрдп рдПрдХ рдХрд╛рдлреА рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдорд╛рдЗрдХреНрд░реЛрдмреНрд▓реЙрдЧрд┐рдВрдЧ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╡рд┐рдХрд╕рд┐рдд рдХрд░рдирд╛ рд╣реИ, рдЬрд┐рд╕реЗ рдореИрдВрдиреЗ рдореМрд▓рд┐рдХрддрд╛ рдХреА рдЕрдиреБрдкрд╕реНрдерд┐рддрд┐ рдореЗрдВ рдорд╛рдЗрдХреНрд░реЛрдмреНрд▓реЙрдЧ рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рд▓рд┐рдпрд╛ред



рд╕рд╛рдордЧреНрд░реА рдХреА рддрд╛рд▓рд┐рдХрд╛:
рднрд╛рдЧ 1: рд╣реИрд▓реЛ рд╡рд░реНрд▓реНрдб!

рднрд╛рдЧ 2: рдЯреЗрдореНрдкрд▓реЗрдЯ

рднрд╛рдЧ 3: рдкреНрд░рдкрддреНрд░

рднрд╛рдЧ 4: рдбреЗрдЯрд╛рдмреЗрд╕

рднрд╛рдЧ 5: рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд▓реЙрдЧрд┐рди

рднрд╛рдЧ 6: рдкреНрд░реЛрдлрд╛рдЗрд▓ рдкреЗрдЬ рдФрд░ рдЕрд╡рддрд╛рд░ (рдпрд╣ рд▓реЗрдЦ)

рднрд╛рдЧ 7: рдпреВрдирд┐рдЯ рдкрд░реАрдХреНрд╖рдг

рднрд╛рдЧ 8: рдЕрдиреБрдпрд╛рдпреА, рд╕рдВрдкрд░реНрдХ рдФрд░ рдорд┐рддреНрд░

рднрд╛рдЧ 9: рдЕрдВрдХреБрд░рдг

рднрд╛рдЧ 10: рдкреВрд░реНрдг рдкрд╛рда рдЦреЛрдЬ

рднрд╛рдЧ 11: рдИрдореЗрд▓ рд╕рдорд░реНрдерди

рднрд╛рдЧ 12: рдкреБрдирд░реНрдирд┐рд░реНрдорд╛рдг

рднрд╛рдЧ 13: рддрд┐рдерд┐ рдФрд░ рд╕рдордп

рднрд╛рдЧ 14: I18n рдФрд░ L10n

рднрд╛рдЧ 15: рдЕрдЬрд╛рдХреНрд╕

рднрд╛рдЧ 16: рдбрд┐рдмрдЧрд┐рдВрдЧ, рдкрд░реАрдХреНрд╖рдг рдФрд░ рдкреНрд░реЛрдлрд╛рдЗрд▓рд┐рдВрдЧ

рднрд╛рдЧ 17: рд▓рд┐рдирдХреНрд╕ рдкрд░ рддреИрдирд╛рддреА (рдФрд░ рд░рд╛рд╕реНрдкрдмреЗрд░реА рдкрд╛рдИ рдкрд░ рднреА!)

рднрд╛рдЧ 18: рд╣рд░реЛрдХреВ рдХреНрд▓рд╛рдЙрдб рдкрд░ рддреИрдирд╛рддреА





рд╕рдВрдХреНрд╖рд┐рдкреНрдд рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐


рдкрд┐рдЫрд▓реЗ рд▓реЗрдЦ рдореЗрдВ, рд╣рдордиреЗ рдПрдХ рдкреНрд░рд╛рдзрд┐рдХрд░рдг рдкреНрд░рдгрд╛рд▓реА рдмрдирд╛рдИ рдереА, рдЕрдм рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдУрдкрдирдЖрдИрдбреА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕рд╛рдЗрдЯ рдкрд░ рд▓реЙрдЧ рдЗрди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред



рдЖрдЬ рд╣рдо рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░реЗрдВрдЧреЗред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдПрдХ рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓ рдкреГрд╖реНрда рдмрдирд╛рдПрдВ, рдЬрд┐рд╕ рдкрд░ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдФрд░ рдЙрд╕рдХреЗ рдкрджреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рдкреНрд░рджрд░реНрд╢рд┐рдд рдХреА рдЬрд╛рдПрдЧреА, рд╣рдо рдпрд╣ рднреА рд╕реАрдЦреЗрдВрдЧреЗ рдХрд┐ рдЕрд╡рддрд╛рд░ рдХреИрд╕реЗ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПред рдФрд░ рдлрд┐рд░ рд╣рдо рд╡реНрдпрдХреНрддрд┐рдЧрдд рдбреЗрдЯрд╛ рдХреЛ рд╕рдВрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдлреЙрд░реНрдо рдмрдирд╛рдПрдВрдЧреЗред



рдкреНрд░реЛрдлрд╛рдЗрд▓ рдкреЗрдЬред


рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдкреНрд░реЛрдлрд╛рдЗрд▓ рдкреЗрдЬ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рд╕реА рдирдИ рдЕрд╡рдзрд╛рд░рдгрд╛ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реЛрддреА рд╣реИред рд╣рдо рдмрд╕ рдЗрд╕рдХреЗ рд▓рд┐рдП рдПрдХ рдирдпрд╛ рджреГрд╢реНрдп рдФрд░ рдПрдХ HTML рдЯреЗрдореНрдкрд▓реЗрдЯ рдмрдирд╛рддреЗ рд╣реИрдВред



рджреЗрдЦрдиреЗ рдореЗрдВ рдлрдВрдХреНрд╢рдиред (рдлрд╝рд╛рдЗрд▓ app.views.py ):



@app.route('/user/<nickname>') @login_required def user(nickname): user = User.query.filter_by(nickname = nickname).first() if user == None: flash('User ' + nickname + ' not found.') return redirect(url_for('index')) posts = [ { 'author': user, 'body': 'Test post #1' }, { 'author': user, 'body': 'Test post #2' } ] return render_template('user.html', user = user, posts = posts)
      
      





App.route рдбреЗрдХреЛрд░реЗрдЯрд░ рд╣рдорд╛рд░реЗ рджреНрд╡рд╛рд░рд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рд╕реЗ рдереЛрдбрд╝рд╛ рдЕрд▓рдЧ рд╣реЛрдЧрд╛ред

рд╡рд┐рдзрд┐ рдореЗрдВ рдЙрдкрдирд╛рдо рд╡рд╛рд▓рд╛ рдПрдХ рдкреИрд░рд╛рдореАрдЯрд░ рд╣реИред рдЖрдкрдХреЛ рд╕рдорд╛рди рдирд╛рдо рдХреЗ рд╕рд╛рде рд╡реНрдпреВ рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рдПрдХ рдкреИрд░рд╛рдореАрдЯрд░ рдЬреЛрдбрд╝рдиреЗ рдХреА рднреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдЬрдм рдХреНрд▓рд╛рдЗрдВрдЯ URL / рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ / рдорд┐рдЧреБрдПрд▓ рдХрд╛ рдЕрдиреБрд░реЛрдз рдХрд░рддрд╛ рд╣реИ, рддреЛ рджреГрд╢реНрдп рдореЗрдВ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдкреИрд░рд╛рдореАрдЯрд░ рдЙрдкрдирд╛рдо = 'рдорд┐рдЧреБрдПрд▓' рдХреЗ рд╕рд╛рде рдмреБрд▓рд╛рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред



рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдЖрд╢реНрдЪрд░реНрдп рдХреЗ рдмрд┐рдирд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╣рдо рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рдбреЗрдЯрд╛рдмреЗрд╕ рд╕реЗ рдЙрд╕ рдЙрдкрдирд╛рдо рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд▓реЛрдб рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реЗрдВрдЧреЗ рдЬреЛ рд╣рдордиреЗ рдПрдХ рддрд░реНрдХ рдХреЗ рд░реВрдк рдореЗрдВ рд▓рд┐рдпрд╛ рдерд╛ред рдпрджрд┐ рдпрд╣ рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рддреЛ рд╣рдо рдореБрдЦреНрдп рдкреГрд╖реНрда рдкрд░ рдПрдХ рддреНрд░реБрдЯрд┐ рд╕рдВрджреЗрд╢ рдХреЗ рд╕рд╛рде рд░реАрдбрд╛рдпрд░реЗрдХреНрдЯ рдХрд░реЗрдВрдЧреЗ, рдЬреИрд╕рд╛ рдХрд┐ рд╣рдордиреЗ рдкрд┐рдЫрд▓реЗ рдЕрдзреНрдпрд╛рдп рдореЗрдВ рдХрд┐рдпрд╛ рдерд╛ред



рдЬреИрд╕реЗ рд╣реА рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╣реЛрддрд╛ рд╣реИ, рд╣рдо рдПрдХ рдкрд░реАрдХреНрд╖рдг рд╕рдВрджреЗрд╢ рдХреЗ рд╕рд╛рде рд░реЗрдВрдбрд░_рдЯреЗрдордкреНрд▓реЗрдЯ рдХрд╣рддреЗ рд╣реИрдВред рдореИрдВ рдЗрд╕ рддрдереНрдп рдкрд░ рдЖрдкрдХрд╛ рдзреНрдпрд╛рди рдЖрдХрд░реНрд╖рд┐рдд рдХрд░рддрд╛ рд╣реВрдВ рдХрд┐ рдЗрд╕ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЗ рд╕рдВрджреЗрд╢ рдХреЗрд╡рд▓ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЗ рдкреГрд╖реНрда рдкрд░ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд┐рдП рдЬрд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЖрдкрдХреЛ рд▓реЗрдЦрдХ рд╕рдореВрд╣ рдХреЛ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рднрд░рдирд╛ рд╣реЛрдЧрд╛ред



рд╣рдорд╛рд░рд╛ рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдХрд╛рдлреА рд╕рд░рд▓ рд▓рдЧрддрд╛ рд╣реИ (рдлрд╝рд╛рдЗрд▓ рдРрдк / рдЯреЗрдореНрдкреНрд▓реЗрдЯ / рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ред



 <!-- extend base layout --> {% extends "base.html" %} {% block content %} <h1>User: {{user.nickname}}!</h1> <hr> {% for post in posts %} <p> {{post.author.nickname}} says: <b>{{post.body}}</b> </p> {% endfor %} {% endblock %}
      
      





рд╣рдо рдкреНрд░реЛрдлрд╛рдЗрд▓ рдкреЗрдЬ рдХреЗ рд╕рд╛рде рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдХрд╣реАрдВ рднреА рдЗрд╕рдХрд╛ рдХреЛрдИ рд▓рд┐рдВрдХ рдирд╣реАрдВ рд╣реИред рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рдЙрдирдХреА рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓ рдкрд░ рд▓рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╕рд╛рди рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдЗрд╕реЗ рд╢реАрд░реНрд╖ рдиреЗрд╡рд┐рдЧреЗрд╢рди рдкреИрдирд▓ рдореЗрдВ рдПрдХ рд▓рд┐рдВрдХ рдЬреЛрдбрд╝реЗрдВрдЧреЗ (рдлрд╝рд╛рдЗрд▓ рдРрдк / рдЯреЗрдореНрдкреНрд▓реЗрдЯ / рдмреЗрд╕.html ):



  <div>Microblog: <a href="{{ url_for('index') }}">Home</a> {% if g.user.is_authenticated() %} | <a href="{{ url_for('user', nickname = g.user.nickname) }}">Your Profile</a> | <a href="{{ url_for('logout') }}">Logout</a> {% endif %} </div>
      
      





рдХреГрдкрдпрд╛ рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рд╣рдордиреЗ url_for рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рдЙрдкрдирд╛рдо рдкреИрд░рд╛рдореАрдЯрд░ рдЬреЛрдбрд╝ рджрд┐рдпрд╛ рд╣реИред



рдЖрдЗрдП рджреЗрдЦреЗрдВ рдХрд┐ рд╣рдореЗрдВ рдХреНрдпрд╛ рдорд┐рд▓рд╛ред You Profile рдкрд░ рдХреНрд▓рд┐рдХ рдХрд░рдХреЗ рд╣рдореЗрдВ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЗ рдкреЗрдЬ рдкрд░ рдЬрд╛рдирд╛ рд╣реЛрдЧрд╛ред рдЪреВрдВрдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЕрдиреНрдп рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреЗ рдкреГрд╖реНрдареЛрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рднреА рд▓рд┐рдВрдХ рдирд╣реАрдВ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЖрдкрдХреЛ рдХрд┐рд╕реА рдЕрдиреНрдп рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреА рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓ рджреЗрдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ URL рджрд░реНрдЬ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдорд┐рдЧреБрдПрд▓ рдХреЗ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓ рдХреЛ рджреЗрдЦрдиреЗ рдХреЗ рд▓рд┐рдП http://localhost:5000/user/miguel



рдЯрд╛рдЗрдк рдХрд░реЗрдВред



рдЕрд╡рддрд╛рд░ред


рдЕрдм рд╣рдорд╛рд░реЗ рдкреНрд░реЛрдлрд╛рдЗрд▓ рдкреЗрдЬ рд╕реБрд╕реНрдд рд╣реИрдВред рдЖрдЗрдП рдЙрдиреНрд╣реЗрдВ рдФрд░ рдЕрдзрд┐рдХ рд░реЛрдЪрдХ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрд╡рддрд╛рд░ рдЬреЛрдбрд╝реЗрдВред



рдЕрдм рд╣рдо рдПрдХ рд╡рд┐рдзрд┐ рд▓рд┐рдЦреЗрдВрдЧреЗ рдЬреЛ рдПрдХ рдЕрд╡рддрд╛рд░ рдХреЛ рд▓реМрдЯрд╛рдПрдЧреА рдФрд░ рдЙрд╕реЗ рдПрдХ рдХрдХреНрд╖рд╛ рдореЗрдВ рдбрд╛рд▓ рджреЗрдЧреА ( app / model.py )



 from hashlib import md5 # ... class User(db.Model): # ... def avatar(self, size): return 'http://www.gravatar.com/avatar/' + md5(self.email).hexdigest() + '?d=mm&s=' + str(size)
      
      





рдЕрд╡рддрд╛рд░ рд╡рд┐рдзрд┐ рдЕрд╡рддрд╛рд░ рдХреЛ рдкрде рд▓реМрдЯрд╛рдПрдЧрд╛, рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдЖрдХрд╛рд░ рдХреЗ рд▓рд┐рдП рд╕рдВрдХреБрдЪрд┐рддред



Gravatar рдпрд╣ рдмрд╣реБрдд рдЖрд╕рд╛рди рдмрдирд╛рдиреЗ рдореЗрдВ рдорджрдж рдХрд░реЗрдЧрд╛ред рдЖрдкрдХреЛ рдмрд╕ рдИрдореЗрд▓ рд╕реЗ рдПрдХ MD5 рд╣реИрд╢ рдмрдирд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдФрд░ рдлрд┐рд░ рдЗрд╕реЗ рдХрд╕реНрдЯрдо URL рдореЗрдВ рдЬреЛрдбрд╝реЗрдВ рдЬреЛ рдКрдкрд░ рдерд╛ред рд╣реИрд╢ рдХреЗ рдмрд╛рдж, URL рдореЗрдВ рдЕрдиреНрдп рдкреИрд░рд╛рдореАрдЯрд░ рдЬреЛрдбрд╝реЗрдВред d = mm рдЗрдВрдЧрд┐рдд рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдЖрдк рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдЫрд╡рд┐ рд╡рд╛рдкрд╕ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдЬрдм рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЗ рдкрд╛рд╕ Gravatar рдЦрд╛рддрд╛ рдирд╣реАрдВ рд╣реИред рдорд┐рдореА рдкреИрд░рд╛рдореАрдЯрд░ рдПрдХ рдЖрджрдореА рдХреЗ рдЧреНрд░реЗ рд╕рд┐рд▓реНрд╣реВрдЯ рдХреЗ рд╕рд╛рде рдПрдХ рдЫрд╡рд┐ рджреЗрддрд╛ рд╣реИред S = N рдкреИрд░рд╛рдореАрдЯрд░ рдЗрдВрдЧрд┐рдд рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдЕрд╡рддрд╛рд░ рдХреЛ рдХрд┐рд╕ рдЖрдХрд╛рд░ рдореЗрдВ рдмрдврд╝рд╛рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред



Gravatar рдХреЗ рд▓рд┐рдП рдкреНрд░рд▓реЗрдЦрдиред



рдЕрдм рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╡рд░реНрдЧ рдЫрд╡рд┐ рдХреЛ рд╡рд╛рдкрд╕ рдХрд░рдирд╛ рдЬрд╛рдирддрд╛ рд╣реИ, рд╣рдо рдЗрд╕реЗ рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓ рдкреГрд╖реНрда (рдлрд╝рд╛рдЗрд▓ рдРрдк / рдЯреЗрдореНрдкреНрд▓реЗрдЯ / рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ред Html) рдореЗрдВ рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ:



 <!-- extend base layout --> {% extends "base.html" %} {% block content %} <table> <tr valign="top"> <td><img src="{{user.avatar(128)}}"></td> <td><h1>User: {{user.nickname}}</h1></td> </tr> </table> <hr> {% for post in posts %} <p> {{post.author.nickname}} says: <b>{{post.body}}</b> </p> {% endfor %} {% endblock %}
      
      





рдпрд╣ рдЙрд▓реНрд▓реЗрдЦрдиреАрдп рд╣реИ рдХрд┐ рдЕрд╡рддрд╛рд░ рдХреЛ рд╡рд╛рдкрд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╡рд░реНрдЧ рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╣реИ, рдФрд░ рдЕрдЧрд░ рдПрдХ рдмрд┐рдВрджреБ рдкрд░ рд╣рдордиреЗ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛ рдХрд┐ рдЧреНрд░реЗрд╡рд╛рд░реНрдЯ рд╡рд╣ рдирд╣реАрдВ рд╣реИ рдЬреЛ рд╣рдо рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рд╣рдо рдЕрд╡рддрд╛рд░ рд╡рд┐рдзрд┐ рдХреЛ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрддреЗ рд╣реИрдВ, рддрд╛рдХрд┐ рдпрд╣ рдПрдХ рдЕрд▓рдЧ рд░рд╛рд╕реНрддрд╛ рд▓реМрдЯрд╛рдПрдЧрд╛ (рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рд╣рдо рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рд╕рд░реНрд╡рд░ рдкрд░ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рддреЗ рд╣реИрдВ), рд╣рдорд╛рд░реЗ рд╕рднреА рдЯреЗрдореНрдкрд▓реЗрдЯ рдирдП рдЕрд╡рддрд╛рд░ рдХреЗ рд╕рд╛рде рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдкреНрд░рд╕реНрддреБрдд рдХрд┐рдП рдЬрд╛рдПрдВрдЧреЗред

рд╣рдордиреЗ рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓ рдкреГрд╖реНрда рдХреЗ рд╢реАрд░реНрд╖ рдкрд░ рдПрдХ рдЕрд╡рддрд╛рд░ рдЬреЛрдбрд╝рд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдкреГрд╖реНрда рдХреЗ рдирд┐рдЪрд▓реЗ рднрд╛рдЧ рдореЗрдВ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рд╕рдВрджреЗрд╢ рд╣реЛрддреЗ рд╣реИрдВ рдЬрд┐рдирдХреЗ рд▓рд┐рдП рдПрдХ рдЫреЛрдЯрд╛ рдЕрд╡рддрд╛рд░ рджрд┐рдЦрд╛рдирд╛ рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛ред рдкреНрд░реЛрдлрд╛рдЗрд▓ рдкреЗрдЬ рдХреЗ рд▓рд┐рдП, рд╣рдо, рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ, рд╕рднреА рд╕рдВрджреЗрд╢реЛрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рд╣реА рдЕрд╡рддрд╛рд░ рджрд┐рдЦрд╛рдПрдВрдЧреЗ, рд▓реЗрдХрд┐рди рдлрд┐рд░, рдЬрдм рд╣рдо рдЗрд╕ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЛ рдореБрдЦреНрдп рдкреГрд╖реНрда рдкрд░ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░реЗрдВрдЧреЗ, рддреЛ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рд╣рд░ рд╕рдВрджреЗрд╢ рд╕рдВрджреЗрд╢ рдХреЗ рд▓реЗрдЦрдХ рдХреЗ рдЕрд╡рддрд╛рд░ рдХреЗ рд╕рд╛рде рд╕рдЬрд╛рдпрд╛ рдЬрд╛рдПрдЧрд╛, рдФрд░ рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛ред

рдкреЛрд╕реНрдЯ рдХреЗ рд▓рд┐рдП рдЕрд╡рддрд╛рд░ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдореЗрдВ рдЫреЛрдЯреЗ рдмрджрд▓рд╛рд╡ рдХрд░реЗрдВрдЧреЗ (рдлрд╛рдЗрд▓ рдПрдк / рдЯреЗрдореНрдкреНрд▓реЗрдЯ / рдпреВрдЬрд░ред Html ):



 <!-- extend base layout --> {% extends "base.html" %} {% block content %} <table> <tr valign="top"> <td><img src="{{user.avatar(128)}}"></td> <td><h1>User: {{user.nickname}}</h1></td> </tr> </table> <hr> {% for post in posts %} <table> <tr valign="top"> <td><img src="{{post.author.avatar(50)}}"></td><td><i>{{post.author.nickname}} says:</i><br>{{post.body}}</td> </tr> </table> {% endfor %} {% endblock %}
      
      





рдЕрдм рд╣рдорд╛рд░реА рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрд╛рдИ рджреЗрдЧреА:

рдЫрд╡рд┐



рдкреБрди: рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдЙрдк-рд╕рдореВрд╣ (рдЙрдк-рдЯреЗрдореНрдкрд▓реЗрдЯ)


рд╣рдордиреЗ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рджреНрд╡рд╛рд░рд╛ рд▓рд┐рдЦрд┐рдд рд╕рдВрджреЗрд╢реЛрдВ рдХреЛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓ рдкреГрд╖реНрда рд╡рд┐рдХрд╕рд┐рдд рдХрд┐рдпрд╛ рд╣реИред рд╣рдорд╛рд░рд╛ рдореБрдЦреНрдп рдкреГрд╖реНрда рдХрд┐рд╕реА рднреА рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХрд╛, рд▓реЗрдХрд┐рди рд╕рдВрджреЗрд╢ рднреА рджрд┐рдЦрд╛рддрд╛ рд╣реИред рдЕрдм рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рджреЛ рдкреНрд░рдХрд╛рд░ рдХреЗ рдЯреЗрдореНрдкрд▓реЗрдЯ рд╣реИрдВ рдЬреЛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рджреНрд╡рд╛рд░рд╛ рд▓рд┐рдЦреЗ рдЧрдП рд╕рдВрджреЗрд╢реЛрдВ рдХреЛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░реЗрдВрдЧреЗред рд╣рдо рдХреЗрд╡рд▓ рдЙрд╕ рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдХреЗ рднрд╛рдЧ рдХреЛ рдХреЙрдкреА / рдкреЗрд╕реНрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рд╕рдВрджреЗрд╢ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд╝рд┐рдореНрдореЗрджрд╛рд░ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рд╡рд┐рдЪрд╛рд░ рдирд╣реАрдВ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдЬрдм рдЖрдкрдХреЛ рд╕рдВрджреЗрд╢ рдХреЗ рдбрд┐рдЬрд╝рд╛рдЗрди рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрди рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рддреЛ рд╣рдореЗрдВ рдЙрди рд╕рднреА рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдХреЛ рдпрд╛рдж рд░рдЦрдирд╛ рдЪрд╛рд╣рд┐рдП рдЬреЛ рд╕рдВрджреЗрд╢ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред



рдЗрд╕рдХреЗ рдмрдЬрд╛рдп, рд╣рдо рдПрдХ рд╕рдмрдкреИрдЯрд░реНрди рдмрдирд╛рдПрдВрдЧреЗ рдЬреЛ рд╕рдВрджреЗрд╢ рдЙрддреНрдкрдиреНрди рдХрд░реЗрдЧрд╛, рдлрд┐рд░ рдмрд╕ рдЙрдкрдкрдЯреНрдЯ рдХреЛ рдХрдиреЗрдХреНрдЯ рдХрд░реЗрдВ, рдЬрд╣рд╛рдВ рдЗрд╕рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛ (рдлрд╝рд╛рдЗрд▓ /app/templates/post.html):



 <table> <tr valign="top"> <td><img src="{{post.author.avatar(50)}}"></td><td><i>{{post.author.nickname}} says:</i><br>{{post.body}}</td> </tr> </table>
      
      





рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдПрдХ рд╕рдВрджреЗрд╢ рдЙрдкрдкрдЯреНрдЯ рдмрдирд╛рддреЗ рд╣реИрдВ рдЬреЛ рдПрдХ рдирд┐рдпрдорд┐рдд рдЯреЗрдореНрдкрд▓реЗрдЯ рд╕реЗ рдЕрд▓рдЧ рдирд╣реАрдВ рд╣реИред рд╣рдо рдЕрдкрдиреЗ рдЯреЗрдореНрдкрд▓реЗрдЯ рд╕реЗ рд╕рдВрджреЗрд╢ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП HTML рдХреЛрдб рд▓реЗрддреЗ рд╣реИрдВред



рдлрд┐рд░ рд╣рдо рд╢рд╛рдорд┐рд▓ рдХрдорд╛рдВрдб (рдлрд╝рд╛рдЗрд▓ рдРрдк / рдЯреЗрдореНрдкреНрд▓реЗрдЯ / рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ред Html ) рдХреЗ рд╕рд╛рде рдЬрд┐рдирдЬрд╛ 2 рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЕрдкрдиреЗ рдЯреЗрдореНрдкрд▓реЗрдЯ рд╕реЗ рдЙрдкрдкрдЯреНрдЯ рдХреЛ рдХреЙрд▓ рдХрд░реЗрдВрдЧреЗ:



 <!-- extend base layout --> {% extends "base.html" %} {% block content %} <table> <tr valign="top"> <td><img src="{{user.avatar(128)}}"></td> <td><h1>User: {{user.nickname}}</h1></td> </tr> </table> <hr> {% for post in posts %} {% include 'post.html' %} {% endfor %} {% endblock %}
      
      





рдЬреИрд╕реЗ рд╣реА рд╣рдо рдХрд╛рд░реНрдпрд╢реАрд▓ рдореБрдЦреНрдп рдкреГрд╖реНрда рдмрдирд╛рддреЗ рд╣реИрдВ, рд╣рдо рдЙрд╕реА рдЙрдкрдкрдЯреНрдЯ рдХрд╛ рдЙрд▓реНрд▓реЗрдЦ рдХрд░реЗрдВрдЧреЗ рдЬрдм рддрдХ рдХрд┐ рд╣рдо рдЗрд╕рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рди рд╣реЛрдВ, рдЗрд╕рд▓рд┐рдП рд╣рдо рдЗрд╕реЗ рдЕрдЧрд▓реЗ рдЕрдзреНрдпрд╛рдп рдХреЗ рд▓рд┐рдП рдЫреЛрдбрд╝ рджреЗрдВрдЧреЗред



рдЕрдзрд┐рдХ рд░реЛрдЪрдХ рдкреНрд░реЛрдлрд╛рдЗрд▓


рдЕрдм рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рдЕрдЪреНрдЫрд╛ рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓ рдкреГрд╖реНрда рд╣реИ, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рдЬрд╛рдирдХрд╛рд░реА рдирд╣реАрдВ рд╣реИред рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЕрдкрдиреЗ рдкреГрд╖реНрдареЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреБрдЫ рдЬрд╛рдирдХрд╛рд░реА рдЬреЛрдбрд╝рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рд╣рдо рдЙрдиреНрд╣реЗрдВ рдпрд╣ рдмрдврд╝рд╛рд╡рд╛ рджреЗрдВрдЧреЗ рдФрд░ рдЗрд╕реЗ рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓ рдкреГрд╖реНрда рдкрд░ рднреА рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░реЗрдВрдЧреЗред рд╣рдо рддрдм рднреА рдЯреНрд░реИрдХ рдХрд░реЗрдВрдЧреЗ рдЬрдм рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдиреЗ рдЕрдВрддрд┐рдо рдмрд╛рд░ рд╕рд╛рдЗрдЯ рджреЗрдЦреА рдереА рдФрд░ рд╣рдо рдЗрд╕реЗ рдкреНрд░реЛрдлрд╛рдЗрд▓ рдкреЗрдЬ рдкрд░ рднреА рджрд┐рдЦрд╛рдПрдВрдЧреЗред



рд╣рдорд╛рд░реА рдпреЛрдЬрдирд╛ рдХреЛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЛ рдмрджрд▓рдирд╛ рд╣реЛрдЧрд╛ред рд╣рдореЗрдВ рдЕрдкрдиреЗ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╡рд░реНрдЧ рдХреЗ рд▓рд┐рдП рджреЛ рдирдП рдлрд╝реАрд▓реНрдб рдЬреЛрдбрд╝рдиреЗ рд╣реЛрдВрдЧреЗ (рдлрд╝рд╛рдЗрд▓ рдПрдкреНрд▓рд┐рдХреЗрд╢рди / рдореЙрдбрд▓ рдУрдбреАрдПрдо):



 class User(db.Model): id = db.Column(db.Integer, primary_key = True) nickname = db.Column(db.String(64), unique = True) email = db.Column(db.String(120), index = True, unique = True) role = db.Column(db.SmallInteger, default = ROLE_USER) posts = db.relationship('Post', backref = 'author', lazy = 'dynamic') about_me = db.Column(db.String(140)) last_seen = db.Column(db.DateTime)
      
      





рдЬрдм рднреА рд╣рдо рдбреЗрдЯрд╛рдмреЗрд╕ рдмрджрд▓рддреЗ рд╣реИрдВ, рд╣рдо рдПрдХ рдирдпрд╛ рдорд╛рдЗрдЧреНрд░реЗрд╢рди рдмрдирд╛рддреЗ рд╣реИрдВред рдпрд╛рдж рд░рдЦреЗрдВ рдХрд┐ рдХреИрд╕реЗ, рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ, рд╣рдо рдбреЗрдЯрд╛рдмреЗрд╕ рдорд╛рдЗрдЧреНрд░реЗрд╢рди рд╕рд┐рд╕реНрдЯрдо рдХреА рд╕реНрдерд╛рдкрдирд╛ рдХреЗ рд▓рд┐рдП рдереНрд░реЛрдЬрд╝ рд╕реЗ рдЧреБрдЬрд░реЗред рдЕрдм рд╣рдо рдЗрди рдкреНрд░рдпрд╛рд╕реЛрдВ рдХрд╛ рд▓рд╛рдн рдЙрдард╛ рд░рд╣реЗ рд╣реИрдВред рд╣рдорд╛рд░реЗ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рдирдП рдлрд╝реАрд▓реНрдб рдЬреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП, рдмрд╕ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░реЗрдВ:



./db_migrate.py



рдФрд░ рд╣рдореЗрдВ рдЬрд╡рд╛рдм рдорд┐рд▓рддрд╛ рд╣реИ:

рдирдпрд╛ рдорд╛рдЗрдЧреНрд░реЗрд╢рди db_repository / рд╕рдВрд╕реНрдХрд░рдгреЛрдВ / 003_migration.py рдХреЗ рд░реВрдк рдореЗрдВ рд╕рд╣реЗрдЬрд╛ рдЧрдпрд╛

рд╡рд░реНрддрдорд╛рди рдбреЗрдЯрд╛рдмреЗрд╕ рд╕рдВрд╕реНрдХрд░рдг: 3


рдФрд░ рд╣рдорд╛рд░реЗ рджреЛ рдирдП рдлрд╝реАрд▓реНрдб рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рдЬреЛрдбрд╝реЗ рдЬрд╛рддреЗ рд╣реИрдВред рдпрд╣ рдордд рднреВрд▓реЛ рдХрд┐ рдпрджрд┐ рдЖрдк рд╡рд┐рдВрдбреЛрдЬ рдкрд░ рд╣реИрдВ рддреЛ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЪрд▓рд╛рдиреЗ рдХрд╛ рдорд╛рд░реНрдЧ рдЕрд▓рдЧ рд╣реИред

рдпрджрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдорд╛рдЗрдЧреНрд░реЗрд╢рди рд╕рд┐рд╕реНрдЯрдо рдирд╣реАрдВ рд╣реИ, рддреЛ рдЖрдкрдХреЛ рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЛ рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рд╕рдВрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдпрд╛ рдЗрд╕рд╕реЗ рднреА рдмрджрддрд░, рдЗрд╕реЗ рд╣рдЯрд╛ рджреЗрдВ рдФрд░ рдЗрд╕реЗ рдлрд┐рд░ рд╕реЗ рдмрдирд╛рдПрдВред



рдЕрдм рдЗрди рдлрд╝реАрд▓реНрдбреНрд╕ рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрддреЗ рд╣реБрдП рдкреНрд░реЛрдлрд╛рдЗрд▓ рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдореЗрдВ рдмрджрд▓рд╛рд╡ рдХрд░реЗрдВ (рдлрд╝рд╛рдЗрд▓ рдРрдк / рдЯреЗрдореНрдкреНрд▓реЗрдЯ / user.html ):



 <!-- extend base layout --> {% extends "base.html" %} {% block content %} <table> <tr valign="top"> <td><img src="{{user.avatar(128)}}"></td> <td> <h1>User: {{user.nickname}}</h1> {% if user.about_me %}<p>{{user.about_me}}</p>{% endif %} {% if user.last_seen %}<p><i>Last seen on: {{user.last_seen}}</i></p>{% endif %} </td> </tr> </table> <hr> {% for post in posts %} {% include 'post.html' %} {% endfor %} {% endblock %}
      
      





рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рд╣рдо рдЗрди рдлрд╝реАрд▓реНрдбреНрд╕ рдХреЛ рджрд┐рдЦрд╛рдиреЗ рдХреЗ рд▓рд┐рдП Jijna2 рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рдХреНрдпреЛрдВрдХрд┐ рд╣рдо рдХреЗрд╡рд▓ рдЙрдиреНрд╣реЗрдВ рджрд┐рдЦрд╛рдПрдВрдЧреЗ рдЬрдм рдЙрдирдореЗрдВ рдбреЗрдЯрд╛ рд╣реЛрдЧрд╛ред



рдЕрдм рд╕рднреА рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреЗ рд▓рд┐рдП рджреЛ рдирдП рдлрд╝реАрд▓реНрдб рдЦрд╛рд▓реА рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рдХреБрдЫ рднреА рдкреНрд░рджрд░реНрд╢рд┐рдд рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред



Last_seen рдлрд╝реАрд▓реНрдб рдХреЛ рдмрдирд╛рдП рд░рдЦрдирд╛ рдЖрд╕рд╛рди рд╣реИред рдпрд╛рдж рд░рдЦреЗрдВ рдХрд┐ рдкрд┐рдЫрд▓реЗ рдЕрдзреНрдпрд╛рдп рдореЗрдВ рд╣рдордиреЗ рдкрд╣рд▓реЗ рд╕реЗ рддреИрдпрд╛рд░ рд╣реИрдВрдбрд▓рд░ рдХреЛ рдХреИрд╕реЗ рдмрдирд╛рдпрд╛ рдерд╛ред рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд▓реЙрдЧрд┐рди рд╕рдордп рдЬреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрдЪреНрдЫреА рдЬрдЧрд╣ (рдлрд╝рд╛рдЗрд▓ рдПрдкреНрд▓рд┐рдХреЗрд╢рди / рд╡рд┐рдЪрд╛рд░ )



 from datetime import datetime # ... @app.before_request def before_request(): g.user = current_user if g.user.is_authenticated(): g.user.last_seen = datetime.utcnow() db.session.add(g.user) db.session.commit()
      
      





рдпрджрд┐ рдЖрдк рдЕрдкрдирд╛ рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓ рдкреГрд╖реНрда рджрд░реНрдЬ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рджреЗрдЦреЗрдВрдЧреЗ рдХрд┐ рдЖрдкрдиреЗ рдкрд┐рдЫрд▓реА рдмрд╛рд░ рдХрдм рд╕рд╛рдЗрдЯ рдХрд╛ рджреМрд░рд╛ рдХрд┐рдпрд╛ рдерд╛ рдФрд░ рд╣рд░ рдмрд╛рд░ рдЬрдм рдЖрдк рдкреГрд╖реНрда рдХреЛ рд░реАрдлрд╝реНрд░реЗрд╢ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╕рдордп рдЕрдкрдбреЗрдЯ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рдХреНрдпреЛрдВрдХрд┐ рд╣рд░ рдмрд╛рд░ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдПрдХ рд╕рдВрдХреНрд╖рд┐рдкреНрдд рдЕрдиреБрд░реЛрдз рдХрд░рддрд╛ рд╣реИ, рд╣реИрдВрдбрд▓рд░ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рд╕рдордп рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░реЗрдЧрд╛ред



рдХреГрдкрдпрд╛ рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рд╣рдо рд╕рдордп рдХреЛ рдорд╛рдирдХ рдпреВрдЯреАрд╕реА рд╕рдордп рдХреНрд╖реЗрддреНрд░ рдореЗрдВ рд▓рд┐рдЦрддреЗ рд╣реИрдВред рд╣рдордиреЗ рдкрд┐рдЫрд▓реЗ рдЕрдзреНрдпрд╛рдп рдореЗрдВ рдЗрд╕ рдкрд░ рдЪрд░реНрдЪрд╛ рдХреА, рдХрд┐ рд╣рдо UTC рдореЗрдВ рд╕рднреА рдЯрд╛рдЗрдорд╕реНрдЯреИрдореНрдк рд▓рд┐рдЦрддреЗ рд╣реИрдВ рддрд╛рдХрд┐ рд╡реЗ рдПрдХ рджреВрд╕рд░реЗ рдХреЗ рдЕрдиреБрд░реВрдк рд╣реЛрдВред рдПрдХ рд╕рд╛рдЗрдб рдЗрдлреЗрдХреНрдЯ рд╣реИ, рдпреВрдЯреАрд╕реА рдореЗрдВ рдкреНрд░реЛрдлрд╛рдЗрд▓ рдкреЗрдЬ рдкрд░ рд╕рдордп рднреА рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рд╣рдо рдЗрд╕реЗ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЕрдзреНрдпрд╛рдпреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдореЗрдВ рдареАрдХ рдХрд░реЗрдВрдЧреЗ, рдЬреЛ рдЯрд╛рдЗрдорд╕реНрдЯреИрдореНрдк рдкрд░ рдзреНрдпрд╛рди рдХреЗрдВрджреНрд░рд┐рдд рдХрд░реЗрдЧрд╛ред



рдЕрдм рдЖрдкрдХреЛ "рдореЗрд░реЗ рдмрд╛рд░реЗ рдореЗрдВ" рдлрд╝реАрд▓реНрдб рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕реНрдерд╛рди рдХрд╛ рдЪрдпрди рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдФрд░ рдЗрд╕реЗ рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓ рд╕рдВрдкрд╛рджрди рдкреГрд╖реНрда рдореЗрдВ рд░рдЦрдирд╛ рдЕрдзрд┐рдХ рд╕рд╣реА рд╣реЛрдЧрд╛ред



рдПрдХ рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓ рдХрд╛ рд╕рдВрдкрд╛рджрдиред


рдПрдХ рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓ рд╕рдВрдкрд╛рджрди рдлрд╝реЙрд░реНрдо рдЬреЛрдбрд╝рдирд╛ рдЖрд╢реНрдЪрд░реНрдпрдЬрдирдХ рд░реВрдк рд╕реЗ рдЖрд╕рд╛рди рд╣реИред рдЖрдЗрдП рдПрдХ рд╡реЗрдм рдлрд╝реЙрд░реНрдо (рдлрд╝рд╛рдЗрд▓ рдРрдк / рдлрд╝реЙрд░реНрдо -рдереНрд░реЗрдб ) рдмрдирд╛рдХрд░ рд╢реБрд░реВ рдХрд░реЗрдВ



 from flask.ext.wtf import Form from wtforms import TextField, BooleanField, TextAreaField from wtforms.validators import Required, Length class EditForm(Form): nickname = TextField('nickname', validators = [Required()]) about_me = TextAreaField('about_me', validators = [Length(min = 0, max = 140)])
      
      







рдФрд░ рдЯреЗрдореНрдкреНрд▓реЗрдЯ ( рдРрдк / рдЯреЗрдореНрдкреНрд▓реЗрдЯ / edit.html рдлрд╝рд╛рдЗрд▓ ):



 <!-- extend base layout --> {% extends "base.html" %} {% block content %} <h1>Edit Your Profile</h1> <form action="" method="post" name="edit"> {{form.hidden_tag()}} <table> <tr> <td>Your nickname:</td> <td>{{form.nickname(size = 24)}}</td> </tr> <tr> <td>About yourself:</td> <td>{{form.about_me(cols = 32, rows = 4)}}</td> </tr> <tr> <td></td> <td><input type="submit" value="Save Changes"></td> </tr> </table> </form> {% endblock %}
      
      





рдЕрдВрдд рдореЗрдВ, рд╣рдо рдлрд╝рдВрдХреНрд╢рди рд╣реИрдВрдбрд▓рд░ рд▓рд┐рдЦрддреЗ рд╣реИрдВ (рдлрд╝рд╛рдЗрд▓ рдРрдк / views.py ):



 from forms import LoginForm, EditForm @app.route('/edit', methods = ['GET', 'POST']) @login_required def edit(): form = EditForm() if form.validate_on_submit(): g.user.nickname = form.nickname.data g.user.about_me = form.about_me.data db.session.add(g.user) db.session.commit() flash('Your changes have been saved.') return redirect(url_for('edit')) else: form.nickname.data = g.user.nickname form.about_me.data = g.user.about_me return render_template('edit.html', form = form)
      
      





рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓ рдкреГрд╖реНрда рд╕реЗ рдЗрд╕рдХрд╛ рдПрдХ рд▓рд┐рдВрдХ рдЬреЛрдбрд╝реЗрдВ, рддрд╛рдХрд┐ рдЖрдк рдЖрд╕рд╛рдиреА рд╕реЗ рд╕рдВрдкрд╛рджрди (рдлрд╝рд╛рдЗрд▓ рдРрдк / рдЯреЗрдореНрдкреНрд▓реЗрдЯ / user.html ) рдкрд░ рдЬрд╛ рд╕рдХреЗрдВ :



 <!-- extend base layout --> {% extends "base.html" %} {% block content %} <table> <tr valign="top"> <td><img src="{{user.avatar(128)}}"></td> <td> <h1>User: {{user.nickname}}</h1> {% if user.about_me %}<p>{{user.about_me}}</p>{% endif %} {% if user.last_seen %}<p><i>Last seen on: {{user.last_seen}}</i></p>{% endif %} {% if user.id == g.user.id %}<p><a href="{{url_for('edit')}}">Edit</a></p>{% endif %} </td> </tr> </table> <hr> {% for post in posts %} {% include 'post.html' %} {% endfor %} {% endblock %}
      
      





рд╣рдо рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рд╢рд░реНрдд рдкрд░рд┐рдЪрд╛рд▓рдХреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рдЬрдм рдЖрдк рдХрд┐рд╕реА рдФрд░ рдХреА рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓ рдкрдврд╝рддреЗ рд╣реИрдВ рддреЛ рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓ рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдХреЗ рд▓рд┐рдВрдХ рджрд┐рдЦрд╛рдИ рдирд╣реАрдВ рджреЗрддреЗ рдереЗред



рдпрд╣ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЗ рдкреГрд╖реНрда рдХрд╛ рдирдпрд╛ рд╕реНрдХреНрд░реАрдирд╢реЙрдЯ рдХреИрд╕рд╛ рд╣реИ, рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдПрдХ рдЫреЛрдЯрд╛ рд╡рд┐рд╡рд░рдг рд╣реИред

рдЫрд╡рд┐



рдирд┐рд╖реНрдХрд░реНрд╖ ... рдФрд░ рд╣реЛрдорд╡рд░реНрдХ!


рд╣рдордиреЗ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдкреНрд░реЛрдлрд╝рд╛рдЗрд▓ рдХреЗ рд╕рд╛рде рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рдХрд╛рдо рдХрд┐рдпрд╛ рд╣реИ, рд╣реИ рдирд╛?

рд▓реЗрдХрд┐рди рд╣рдорд╛рд░реА рдПрдХ рдЕрдкреНрд░рд┐рдп рдЧрд▓рддреА рд╣реИ рдФрд░ рд╣рдореЗрдВ рдЗрд╕реЗ рдареАрдХ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред



рдХреНрдпрд╛ рдЖрдк рдЙрд╕реЗ рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВ?



рдЯрд┐рдкред рд╣рдордиреЗ рдкрд┐рдЫрд▓реЗ рдЕрдзреНрдпрд╛рдп рдореЗрдВ рдПрдХ рдЧрд▓рддреА рдХреА рдереА рдЬрдм рд╣рдордиреЗ рдкреНрд░рд╛рдзрд┐рдХрд░рдг рдХрд┐рдпрд╛ рдерд╛ред рдФрд░ рдЖрдЬ рд╣рдордиреЗ рдПрдХ рдирдпрд╛ рдХреЛрдб рдХреЛрдб рд▓рд┐рдЦрд╛ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдПрдХ рд╣реА рддреНрд░реБрдЯрд┐ рд╣реИред



рдЙрд╕реЗ рдЦреЛрдЬрдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реЗрдВ, рдФрд░ рдпрджрд┐ рдЖрдк рдкрд╛рддреЗ рд╣реИрдВ, рддреЛ рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдореЗрдВ рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рд╕реНрд╡рддрдВрддреНрд░ рдорд╣рд╕реВрд╕ рдХрд░реЗрдВред рдореИрдВ рддреНрд░реБрдЯрд┐ рдХреЛ рд╕рдордЭрд╛рдКрдВрдЧрд╛ рдФрд░ рдЗрд╕реЗ рдЕрдЧрд▓реЗ рдЕрдзреНрдпрд╛рдп рдореЗрдВ рдХреИрд╕реЗ рдареАрдХ рдХрд░реВрдВрдЧрд╛ред



рд╣рдореЗрд╢рд╛ рдХреА рддрд░рд╣, рдЖрдЬ рдХреЗ рдмрджрд▓рд╛рд╡реЛрдВ рдХреЗ рд╕рд╛рде рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдбрд╛рдЙрдирд▓реЛрдб рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд▓рд┐рдВрдХ рдпрд╣рд╛рдВ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред



рдореИрдВрдиреЗ рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЛ рдЖрд░реНрдХрд╛рдЗрд╡ рдореЗрдВ рд╢рд╛рдорд┐рд▓ рдирд╣реАрдВ рдХрд┐рдпрд╛ред рдпрджрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рдкрд┐рдЫрд▓реЗ рдЕрдзреНрдпрд╛рдп рдХрд╛ рдбреЗрдЯрд╛рдмреЗрд╕ рд╣реИ, рддреЛ рдмрд╕ рдЗрд╕реЗ рд╕рд╣реА рдЬрдЧрд╣ рдкрд░ рд░рдЦреЗрдВ рдФрд░ db_upgrad.py рдЪрд▓рд╛рдПрдВ ред рдпрджрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рдкрд┐рдЫрд▓реЗ рдбреЗрдЯрд╛рдмреЗрд╕ рдирд╣реАрдВ рд╣реИ, рддреЛ db_create.py рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдПрдХ рдирдпрд╛ рдмрдирд╛рдПрдВ ред



рдореЗрд░реЗ рдЯреНрдпреВрдЯреЛрд░рд┐рдпрд▓ рдХреЛ рдкрдврд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рджред

рдЖрд╢рд╛ рд╣реИ рдХрд┐ рдЖрдк рдЕрдЧрд▓реЗ рдЕрдВрдХ рдореЗрдВ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВред



рдореВрд▓ рд▓реЗрдЦ рдорд┐рдЧреБрдПрд▓ рдЧреНрд░рд┐рдирдмрд░реНрдЧ рдХреЗ рдкреАрдПрд╕ рд▓реЗрдЦрдХ



All Articles