File tree Expand file tree Collapse file tree 5 files changed +104
-1
lines changed Expand file tree Collapse file tree 5 files changed +104
-1
lines changed Original file line number Diff line number Diff line change 11# coding=utf-8
22from __future__ import absolute_import
33from flask_wtf import Form
4+ from flask_login import current_user
45from wtforms import StringField , PasswordField
5- from wtforms .validators import ValidationError , Email , Required
6+ from wtforms .validators import ValidationError , Email , Required , URL
67
78from firefly .models .user import User
89
@@ -39,3 +40,17 @@ def validate_password(self, field):
3940 self .user = user
4041 else :
4142 raise ValidationError ('邮箱或密码错误' )
43+
44+
45+ class ProfileForm (Form ):
46+ location = StringField ('Location' )
47+ website = StringField ('URL' , [URL ()])
48+ github_id = StringField ('Github' )
49+
50+ def save (self ):
51+ user = current_user
52+ if user and not user .is_anonymous ():
53+ user .location = self .location .data
54+ user .website = self .website .data
55+ user .github_id = self .github_id .data
56+ user .save ()
Original file line number Diff line number Diff line change @@ -55,9 +55,16 @@ class User(db.Document, UserMixin):
5555 roles = fields .ListField (
5656 fields .ReferenceField (Role , reverse_delete_rule = DENY ), default = [])
5757
58+ location = db .StringField (max_length = 25 )
59+ website = db .URLField ()
60+ github_id = db .StringField (max_length = 25 )
61+
5862 def __str__ (self ):
5963 return self .cn
6064
65+ def __repr__ (self ):
66+ return '<User id={id} cn={cn}>' .format (cn = self .cn , id = str (self .id ))
67+
6168 def url (self ):
6269 return url_for ('user.detail' , id = str (self .id ))
6370
Original file line number Diff line number Diff line change 1+ {% extends "base.html" %}
2+
3+ {% block title %}
4+ 用户设置
5+ {% endblock %}
6+
7+ {% block outlet %}
8+ < div >
9+ < form id ="settingsform " class ="settings-form " role ="form " method ="post " action ="{{url_for('user.settings')}} ">
10+ < div class ="form-group ">
11+ < input type ="hidden " name ="csrf_token " value ="{{ csrf_token() }} " />
12+ < label class ="control-label " for ="inputLocation "> 地点</ label >
13+ < input id ="inputLocation " class ="form-control " type ="text " value ="{{ user.location if user.location else ''}} " required ="" tabindex ="1 " name ="location "/>
14+ </ div >
15+ < div class ="form-group ">
16+ < label class ="control-label " for ="inputWebsite "> 网站</ label >
17+ < input id ="inputWebsite " class ="form-control " type ="text " value ="{{ user.website if user.website else ''}} " required ="" tabindex ="1 " name ="website "/>
18+ </ div >
19+ < div class ="form-group ">
20+ < label class ="control-label " for ="inputGithub "> Github</ label >
21+ @< input id ="inputGithub " class ="form-control " type ="text " value ="{{ user.github_id if user.github_id else ''}} " required ="" tabindex ="1 " name ="github_id "/>
22+ </ div >
23+ < div class ="form-group ">
24+ < button id ="loginBtn " class ="login-btn btn-default " tabindex ="3 " type ="submit ">
25+ 修改
26+ </ button >
27+ </ div >
28+ </ form >
29+ </ div >
30+ {% endblock %}
31+
32+ {% block head_script %}
33+ < link href ="{{url_for('static', filename='stylesheets/base16-light.css')}} " rel ="stylesheet "/>
34+ < link href ="{{url_for('static', filename='stylesheets/codemirror.css')}} " rel ="stylesheet "/>
35+ < link href ="{{url_for('static', filename='stylesheets/select2.min.css')}} " rel ="stylesheet "/>
36+ < link href ="{{url_for('static', filename='stylesheets/effeckt/list-items.css')}} " rel ="stylesheet "/>
37+ < link href ="{{url_for('static', filename='stylesheets/index.css')}} " rel ="stylesheet " media ="all "/>
38+ {% endblock %}
Original file line number Diff line number Diff line change 11# coding=utf-8
22from __future__ import absolute_import
33
4+ from flask import url_for , redirect
5+
46from flask .views import MethodView
57from flask .blueprints import Blueprint
8+ from flask .ext .login import login_required , current_user
9+ from firefly .libs .template import render_template
10+ from firefly .forms .user import ProfileForm
611
712
813bp = Blueprint ('user' , __name__ , url_prefix = '/user' )
@@ -12,4 +17,17 @@ class UserView(MethodView):
1217 def get (self , id ):
1318 return ''
1419
20+
21+ class UserSettingsView (MethodView ):
22+ decorators = [login_required ]
23+
24+ def get (self ):
25+ return render_template ('user/settings.html' , user = current_user )
26+
27+ def post (self ):
28+ form = ProfileForm ()
29+ form .save ()
30+ return redirect (url_for ('user.settings' ))
31+
1532bp .add_url_rule ('/<id>/' , view_func = UserView .as_view ('detail' ))
33+ bp .add_url_rule ('/settings' , view_func = UserSettingsView .as_view ('settings' ))
Original file line number Diff line number Diff line change @@ -35,6 +35,31 @@ def login(self, user_no):
3535 assert current_user .is_authenticated ()
3636 assert url_for ('security.logout' ) in rv .data
3737
38+ def test_user_settings (self ):
39+ LOCATION = 'Beijing'
40+ WEBSITE = 'http://firefly.dev'
41+ GITHUB_ID = 'firefly'
42+
43+ self .login (0 )
44+ url = url_for ('user.settings' )
45+ assert self .users [0 ].location is None
46+ assert self .users [0 ].website is None
47+ assert self .users [0 ].github_id is None
48+
49+ form = {
50+ 'location' : LOCATION ,
51+ 'website' : WEBSITE ,
52+ 'github_id' : GITHUB_ID
53+ }
54+ rv = self .client .post (url , data = form )
55+ assert rv .status_code == 302
56+
57+ user = User .objects .filter (id = self .users [0 ].id ).first ()
58+ assert user
59+ assert user .location == LOCATION
60+ assert user .website == WEBSITE
61+ assert user .github_id == GITHUB_ID
62+
3863 def test_follow_user_api (self ):
3964 # test follow
4065 self .login (0 )
You can’t perform that action at this time.
0 commit comments