class user_management(wx.Panel):
def login(self):
# Login Function can be later integrated to allow users access to your program
username = self.txt_Username.GetValue()
self.frame.SetStatusText("Welcome "+username+" to the system!!")
test = MyApp(0)
test.MainLoop()
How can i access the variable username within another class:
class wizard(wx.wizard.Wizard):
def on_finished(self, evt):
totalscore = self.totalscore
print "Final score: %s" % (totalscore)
user = "c1021358"
db_file="data/data.db"
database_already_exists = os.path.exists(db_file)
con = sqlite3.connect(db_file)
cur = con.cursor()
sql = "INSERT INTO scores (username,totalscore,topic) VALUES ('%s','%s','%s')" % (user,totalscore,tag)
At the moment the user is static, however I want to make this user variable equal to the username taken from the text field box.
Can anyone tell me how I can do this please?
Thank you
Currently username is a local variable and can't be accessed outside of the method. You could make it a member variable by doing something like self.username instead. It would probably be a good idea to initialize it in an __init__ method.
EDIT: katrielalex has the right idea. You probably want to store the username in something that is not part of your user_management panel. This could either be a global variable, or you could make a user class.
class User:
def __init__(self, username):
self.username = username
# Create a global "current_user", with an initial username of None
current_user = User(None)
Then if you can access the username from the global User object:
def login(self):
global current_user
current_user.username = self.txt_Username.GetValue()
Please note this is all very general (for instance, this assumes you can only support one user at a time), but it should be able to get you started.
Well, you need to store the value of username somewhere that both methods can see. The easiest way to do this, but almost certainly not the right one, is to make it a global variable. You can do that using the global keyword:
global username
username = ...
However, you are almost certainly more likely to want to store it as an attribute of some object. I don't know your architecture so I can't tell you where is best to put it, but something like a User or a Settings object would be good.
Related
I'm not sure what is the best/pythonic way of having a User document that automatically hashes its password upon creating.
Consider the following mongoengine model :
class User(Document):
email = EmailField(required=True, primary_key=True)
name = StringField(required=True)
pswd = StringField(required=True)
def check_pswd(self, password):
return verify_password(password, self.pswd)
def hash_pswd(self, password):
return hash_password(password):
def save(self, *args, **kwargs):
self.pswd = self.hash_pswd(self.pswd)
super().save(*args, **kwargs)
When I create a user, it works fine :
user = User()
user.email = 'user#email.com'
user.pswd = 'password'
user.name = 'User'
user.save()
Buf if I update it, it will double hash its password, I don't want that.
#User wants to change his name
user = User.objects(email='user#email.com')
user.name = 'User 2'
user.save()
Is there a way for me to hash its password only when creating or changing the password?
Or maybe I should delegate the responsibility of hashing the password to the View/Controller?
I am not giving you the code sample, you can use Document.update() method which will update the fields that only has changed.
If you still wanna use the save method,
Then you can create a logic along the following lines.
Check if the user has changed the password(by comparing the existing stored hash and new hash if any)
If the new hash is different then user has changed the password in that case you can push an Document.update method.
If not, don't call update on that field.
Alternatively update in Mongoengine accepts a iterable, so you can simply create a list or a dictionary object and convinently choose to Remove the password hash field from it.
As for who should execute this i.e View / Controller, its a Design decision but I would rather keep Representation (GUI / Front End) seperate from logic, so I would delegate this to the controller or even more Intrinsically to the Object who is responsible for handling all database/network related tasks, this way it would be isolated and easy to modify. And would not complexify or slow the View objects process / thread
Link for update using an iterable like Dict.
stackoverflow question for Mongoengine update using iterable
Link discussing save methods deprecation (The Maintainer Has commented below as save method not being deprecated, so trust him/her and proceed at will on this link)
Mongoengine save method deprecated?
Link for update method in mongoengine.
Mongoengine Atomic Update
For my site for auth I'm using https://flask-httpauth.readthedocs.io/en/latest/ . Now I'm trying to make it that it's using data from database. To do that i created database named Users and created columns named username and password.
To get data from this table after defining its class as model I've made get_user functions which looks like it:
#staticmethod
def get_user():
query = (Users
.select())
user = []
for s in query:
user.append(s)
return user
(I'm not sure if it's correct)
Next I had to modify get_pw function but I also wasn't sure how to modify it so I made it look like it:
#auth.get_password
def get_pw(username):
if username in Users.get_user():
return users.get(Users.get_user())
return None
Now after running the site I get prompt to give login and password but those that I set up in my database doesn't seem to work so there must be a problem with get_pw function. Also I'm using peewee SQL to manage database : http://docs.peewee-orm.com/en/latest/peewee/querying.html
You can get rid of your get_user method since you are issuing a very large select query that fetches all records from user table. The get_pw can be redefined as:
def get_pw(username):
user = Users.get(Users.name == username) #assuming you have a username field in model
return user.password #assuming a password field
Also, its a good practice to define your model class as a singular noun rather than plural. So, its better to call it User rather than Users.
This'll help you get started in no time: http://docs.peewee-orm.com/en/latest/peewee/quickstart.html#quickstart
Let's say Bob enters his name, 'Bob Jones,' into a Tkinter text entry field. Later, I want to be able to access his name like this:
BobJones = {
'name':'Bob Jones',
'pet\'s name':'Fido'
}
How do I make it so I assign whatever Bob inputs as a new variable without having to manually write it in?
Thanks in advance.
To expand on the comments above, I think you'd want something more like this:
# Define the user class - what data do we store about users:
class User(object):
def __init__(self, user_name, first_pet):
self.user_name = user_name
self.first_pet = first_pet
# Now gather the actual list of users
users = []
while someCondition:
user_name, first_pet = getUserDetails()
users.append(User(user_name, first_pet))
# Now we can use it
print "The first users name is:"
print users[0].user_name
So you're defining the class (think of it as a template) for the Users, then creating new User objects, one for each person, and storing them in the users list.
I have a function that gets an image from a form, and put's it into the database along with the username. So, here is my database:
class Imagedb(db.Model):
name = db.StringProperty(required = True)
image = db.BlobProperty()
And here is the code that writes to the database:
class Change_Profile_Image(MainHandler):
def get(self):
if self.user:
self.render('change_profile_image.html', username = self.user.name, firstname=self.user.first_name)
else:
self.render('change_profile_image.html')
def post(self):
imagedb = Imagedb(name = self.user.name)
imageupl = self.request.get("img")
imagedb.image = db.Blob(imageupl)
imagedb.put()
self.redirect('/profile')
Any who, it works awesome. Except for one thing. What i'm trying to accomplish is only storing ONE profile picture. What ends up happening is this:
Say I am the user admin. Ill upload a display pic, that pic shows in the profile. Ill upload another one, that one shows. Cool, except for the fact that I have 2 objects in my database that have the name = admin attribute. I would like to edit this...
def post(self):
imagedb = Imagedb(name = self.user.name)
imageupl = self.request.get("img")
imagedb.image = db.Blob(imageupl)
imagedb.put()
self.redirect('/profile')
so that I can post images to the database, but if one exists, it is overwritten. Could anyone help me with this please? I'm relatively new to python and app engine.
If something is unclear, please let me know.
You want to set the key of the Imagedb entity to "name". Essentially, you don't need the name field, but you'll instantiate it like
imagedb = Imagedb(key_name = self.user.name)
The key is a required field on all entities. By using your user name as the key it means every time you refere to a given key, it's the same entity.
I have a flatland form for a proxy website that looks something like this:
class doSomethingForm(Form):
'''Do an action with account credentials'''
username = String.using(default='',
validators=[Present(), UsernameFormat()])
password = String.using(default='',
validators=[Present(), PasswordFormat()])
action = String.using(default='',
validators=[Present(), ActionFormat()])
If any of the parameters are empty, I want the validation error to be that the given elements are empty. If they are non-empty and meet other requirements, then the next step is to ask the other service if the credentials are valid. If they are invalid, then I want to turn that into a validation error.
This looks a lot like flatland's container-level validation, which runs validation on the contained elements first. So I tried this:
class doSomethingForm(Form):
'''Do an action with account credentials'''
account = Dict.of(
username = String.named('username').using(default='',
validators=[Present(), UsernameFormat()])
password = String.named('password').using(default='',
validators=[Present(), PasswordFormat()])
).using(validators=[CheckCredentials()])
action = String.using(default='',
validators=[Present(), ActionFormat()])
This looks like it would work, but now the form is looking for elements named account_username and account_password, which isn't quite the interface I was hoping for.
I see a couple of solutions:
I could attach the CheckCredentials validator to doSomethingForm. But, I don't see a way to do this in the documentation.
I could attach the CheckCredentials validator to username, which can access its sibling password. However, I don't want to bother the other server if the username and password are in a bad format. so I'd have to run the validations on username and password first, which seems like repeating myself.
I could hack a verson of Dict that doesn't do namespacing
Is there right way to add form-level validators in flatland?
After reading a bit of the docs I would assume you can simply do your_form.validate().
The Form class inherits the Dict class so the way you can do validation is identical to how the container-level validation normally works.
Disclaimer: until your question I've never heard of "flatland" so I can be really off here.
It is useful to checkout the flatland code (hg clone http://bitbucket.org/jek/flatland), because the documentation and examples aren't quite there yet.
Form inherits from Dict, which inherits from Container, which inherits from Element. There are two class elements that will help:
descent_validators (from Container) - an iterable of Validators to run on the descent (first) phase.
validators (from Element) - an iterable of Validators to run on the ascent (second) phase.
To get my desired behavior (check account only if the username and password are valid), I need to add my validator to the validators class variable, and check that the child validators passed.
My code now looks something like this:
class CheckCredentials(Validator):
'''Checks credentials and creates an account object'''
def validate(self, element, state):
username = element['username']
password = element['password']
if not (username.all_valid and password.all_valid):
return false
self.account = Account(username.u, password.u)
return self.account.valid()
class doSomethingForm(Form):
'''Do an action with account credentials'''
username = String.using(default='',
validators=[Present(), UsernameFormat()])
password = String.using(default='',
validators=[Present(), PasswordFormat()])
action = String.using(default='',
validators=[Present(), ActionFormat()])
validators = (CheckCredentials(),)
#expose('/do_something')
def doSomething(request):
form = doSomethingForm.from_defaults()
form.set_flat(request.form)
result_html = ''
method = request.method
if method == 'POST' and not form.validate():
method = 'GET'
errors = []
if form.errors: errors.extend(form.errors)
for el in form.all_children:
if el.errors: errors.extend(el.errors)
result_html = errorsToHtml(errors)
if method == 'POST':
result_html = form.account.action(form['action'].u)
return render_template('do_something.html',
result=result_html, **form.value)
I think flatland can do some cooler things to help with generating the HTML forms, but I'm pretty happy with this so far.
Thanks to WoLpH and jek for their help.