I am struggling to update my users in my update function.
1.The first if: is for making sure the user doesnt forget to input the user name.
2.the else: is to ensure the user input the correct username,
3.then the user can choose what to update between fist and last name, and the password.
But it now only 1 and 2 are working, then when I try to update the first, last or pwd.. it is not updating
def update_user(self, first, last, user, pwd, des):
pwd = hashlib.sha256(pwd.encode()).hexdigest()
if user == '':
self.notify.add_widget(Label(text='[color=#FF0000][b]All Fields Required[/b][/color]',markup=True))
self.notify.open()
Clock.schedule_once(self.killswitch,1)
else:
user = self.user.find_one({'user_name':user})
if user == None:
self.notify.add_widget(Label(text='[color=#FF0000][b]Invalid Username[/b][/color]',markup=True))
self.notify.open()
Clock.schedule_once(self.killswitch,1)
else:
if first == '':
first = user['first_name']
if last == '':
last = user['last_name']
if pwd == '':
pwd = user['password']
self.user.update_one({'user_name':user},{'$set':{'first_name':first,'last_name':last,'user_name':user,'password':pwd,'designation':des,'date':datetime.now()}})
content = self.ids.scn_content
content.clear_widgets()
users = self.get_users()
userstable = DataTable(table=users)
content.add_widget(userstable)
Related
I have two models prodcut_prices and WrongPrice.
In WrongPrice the user can correct report wrong prices - when the price is reported it should also be updated in product_price.
My problem is, even though I instantiate product_price at the very beginning as instance_productprice, all of its required fields returns the "this field has to be filled out" error.
How come those field are not set when im using the instance instance_productprice = product_prices.objects.filter(id=pk)[0] ? Note, that all fields in product_prices are always non-empty since they are being pulled from the product_price model, which is handled in another view, thus that is not the issue.
def wrong_price(request,pk):
#Get the current price object
instance_productprice = product_prices.objects.filter(id=pk)[0]
#Get different values
wrong_link = instance_productprice.link
img_url = instance_productprice.image_url
wrong_price = instance_productprice.last_price
domain = instance_productprice.domain
# Create instances
instance_wrongprice = WrongPrice(
link=wrong_link,
correct_price=wrong_price,
domain = domain)
if request.method == "POST":
form_wrong_price = wrong_price_form(request.POST,instance=instance_wrongprice)
# Update values in product_prices
form_product_price = product_prices_form(request.POST,instance=instance_productprice)
form_product_price.instance.start_price = form_wrong_price.instance.correct_price
form_product_price.instance.last_price = form_wrong_price.instance.correct_price
if form_wrong_price.is_valid() & form_product_price.is_valid():
form_wrong_price.save()
form_product_price.save()
messages.success(request, "Thanks")
return redirect("my_page")
else:
messages.error(request, form_product_price.errors) # Throws empty-field errors,
messages.error(request, form_wrong_price.errors)
return redirect("wrong-price", pk=pk)
else:
form_wrong_price = wrong_price_form(instance=instance_wrongprice)
return render(request, "my_app/wrong_price.html",context={"form":form_wrong_price,"info":{"image_url":img_url}})
I am bit confused about how you implemented it. You have passed a instance of WrongPrice price through the form, which is unnecessary, you could have used initial:
wrong_values = dict(
link=wrong_link,
correct_price=wrong_price,
domain = domain
)
form_wrong_price = wrong_price_form(initial= wrong_values)
Then you are adding values to product_prices_form from instance of form_wrong_price. I don't see why you need a form again here. You can simple use:
form_wrong_price = wrong_price_form(request.POST, initial= wrong_values)
if form_wrong_price.is_valid():
instance = form_wrong_price.save()
instance_productprice.start_price = instance.correct_price
instance_productprice.last_price = instance.correct_price
instance_productprice.save()
Finally, please use PascalCase when defining class names. And you can get the product prices by product_prices.objects.get(id=pk)(instead of filter()[0]).
I created this custom jwt_payload_handler for jwt so that it can be password aware. If a user changes their password, I want previous tokens to expire. But even though I have a custom handler, for some reason drf jwt ignores the changes and still accepts past tokens after I change the user password or change the password_last_change string value.
Am I missing another configuration?
jwt_payload_handler:
def jwt_payload_handler(user):
username_field = get_username_field()
username = get_username(user)
password_last_change = user.password_last_change # getting json not serializable error. constant string for now
warnings.warn(
'The following fields will be removed in the future: '
'`email` and `user_id`. ',
DeprecationWarning
)
payload = {
'user_id': user.pk,
'username': username,
'password': user.password,
'exp': (datetime.utcnow() + api_settings.JWT_EXPIRATION_DELTA) ,
'password_last_change': 'test1',
}
if hasattr(user, 'email'):
payload['email'] = user.email
if isinstance(user.pk, uuid.UUID):
payload['user_id'] = str(user.pk)
payload[username_field] = username
# Include original issued at time for a brand new token,
# to allow token refresh
if api_settings.JWT_ALLOW_REFRESH:
payload['orig_iat'] = timegm(
datetime.utcnow().utctimetuple()
)
if api_settings.JWT_AUDIENCE is not None:
payload['aud'] = api_settings.JWT_AUDIENCE
if api_settings.JWT_ISSUER is not None:
payload['iss'] = api_settings.JWT_ISSUER
return payload
I figured it out. Instead of a custom jwt_payload_handler function we need to set JWT_GET_USER_SECRET_KEY value in the settings.py file. By default it is None but it accepts a function that takes a user as a parameter and returns a uuid string. If not configured, the conf django secret key is used for all users. But if set, each user will have their own secret key.
On password change, also update the uuid.
in the user model we could set some field to:
class TestUser(AbstractBaseUser):
jwt_secret = models.UUIDField(default=uuid.uuid4)
function example:
def jwt_get_secret_key(user_model):
return user_model.jwt_secret
in settings:
JWT_AUTH = {
...
'JWT_GET_USER_SECRET_KEY': 'path.to.jwt_get_secret_key'
...
}
So in your view or signal, after set_password method is called:
you can set the user.secret_jwt to a new value:
user.secret_jwt = uuid.uuid4()
user.save()
Which will make all previous request invalid.
I'm implementing search functionality using Elasticsearch in a "Reddit clone" web application that I'm developing. I want to support searching for threads, users, and subreddits, but when I enter a search query and search for one of the 3 above mentioned categories that does not hold any matches, I'm getting an unexpected "OperationalError" instead of an empty set of results.
As shown in the code I included, I attempted to use the sqlalchemy.orm.query.Query.all() function which returned the following error:
OperationalError: (sqlite3.OperationalError) near "END": syntax error
[SQL: SELECT user.id AS user_id, user.username AS user_username, user.email AS user_email, user.password_hash AS user_password_hash, user.last_sign_in AS user_last_sign_in
FROM user
WHERE 1 != 1 ORDER BY CASE user.id END]
(Background on this error at: http://sqlalche.me/e/e3q8)
I researched other StackOverflow posts and found that the first() function internally processes the database result and returns None if no results are found, but when I switched to that function, I faced this error:
OperationalError: (sqlite3.OperationalError) near "END": syntax error
[SQL: SELECT user.id AS user_id, user.username AS user_username, user.email AS user_email, user.password_hash AS user_password_hash, user.last_sign_in AS user_last_sign_in
FROM user
WHERE 1 != 1 ORDER BY CASE user.id END
LIMIT ? OFFSET ?]
[parameters: (1, 0)]
(Background on this error at: http://sqlalche.me/e/e3q8)
Checking the documentation for SqlAlchemy, I don't see any mention of this error in either function, and reading the meaning of OperationalError, I'm concerned that my database setup is possibly incorrect.
app/routes.py: This is the route that handles search requests made to the following URL: http://localhost:5000/search?q=&index=
#app.route('/search', methods=['GET'])
def search():
print 'Hit the /search route!'
if not g.search_form.validate():
return redirect(url_for('index'))
page = request.args.get('page', 1, type=int)
target_index = request.args.get('index', 'thread')
if target_index == 'thread':
results, total = Thread.search(g.search_form.q.data, page, app.config['POSTS_PER_PAGE'])
print 'Called Thread.search(), total results = {}'.format(total['value'])
elif target_index == 'user':
results, total = User.search(g.search_form.q.data, page, app.config['POSTS_PER_PAGE'])
print 'Called User.search(), total results = {}'.format(total['value'])
elif target_index == 'subreddit':
results, total = Subreddit.search(g.search_form.q.data, page, app.config['POSTS_PER_PAGE'])
print 'Called Subreddit.search(), total results = {}'.format(total['value'])
else:
return render_template('404.html')
try:
results = results.all()
except OperationalError:
results = [None]
total = total['value']
next_url = url_for('search', index=target_index, q=g.search_form.q.data, page=page + 1) if total > page * app.config['POSTS_PER_PAGE'] else None
prev_url = url_for('search', index=target_index, q=g.search_form.q.data, page=page - 1) if page > 1 else None
results_list = zip(results, [None] * len(results)) # Temporarily to match expected input for template
return render_template('search.html', title=_('Search'), results_list=results_list, next_url=next_url, prev_url=prev_url, query=g.search_form.q.data, index=target_index)
app/models.py:
class SearchableMixin(object):
#classmethod
def search(cls, expression, page, per_page):
ids, total = query_index(cls.__tablename__, expression, page, per_page)
if total == 0:
return cls.query.filter_by(id=0), 0
when = []
for i in range(len(ids)):
when.append((ids[i], i))
return cls.query.filter(cls.id.in_(ids)).order_by(
db.case(when, value=cls.id)), total
#classmethod
def before_commit(cls, session):
session._changes = {
'add': list(session.new),
'update': list(session.dirty),
'delete': list(session.deleted)
}
#classmethod
def after_commit(cls, session):
for obj in session._changes['add']:
if isinstance(obj, SearchableMixin):
add_to_index(obj.__tablename__, obj)
for obj in session._changes['update']:
if isinstance(obj, SearchableMixin):
add_to_index(obj.__tablename__, obj)
for obj in session._changes['delete']:
if isinstance(obj, SearchableMixin):
remove_from_index(obj.__tablename__, obj)
session._changes = None
#classmethod
def reindex(cls):
for obj in cls.query:
add_to_index(cls.__tablename__, obj)
db.event.listen(db.session, 'before_commit', SearchableMixin.before_commit)
db.event.listen(db.session, 'after_commit', SearchableMixin.after_commit)
# Below is one model that implements SearchableMixin to allow searching # for users. Thread and Subreddit models follow the same logic.
class User(db.Model, UserMixin, SearchableMixin):
__searchable__ = ['username']
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(64), index=True, unique=True)
# <Remaining User model fields here...>
app/search.py: (Holds the underlying search functions to query Elasticsearch indices)
def add_to_index(index, model):
if not app.elasticsearch:
return
payload = {}
for field in model.__searchable__:
payload[field] = getattr(model, field)
app.elasticsearch.index(index=index, doc_type=index, id=model.id,
body=payload)
def remove_from_index(index, model):
if not app.elasticsearch:
return
app.elasticsearch.delete(index=index, doc_type=index, id=model.id)
def query_index(index, query, page, per_page):
if not app.elasticsearch:
return [], 0
search = app.elasticsearch.search(
index=index,
body={'query': {'multi_match': {'query': query, 'fields': ['*']}},
'from': (page - 1) * per_page, 'size': per_page})
ids = [int(hit['_id']) for hit in search['hits']['hits']]
return ids, search['hits']['total']
As my included app/routes.py shows, I made a workaround by catching the OperationalError and treating it as an indicator that no results were found, but since the all() documentation makes no mention of it, I did not expect there to be this exception being raised.
I simplified the generated query a bit by hiding all fields you retrieve behind the asterisk.
SELECT user.*
FROM user
WHERE 1 != 1
ORDER BY CASE user.id END
First of all, this query will not return any values as long as 1 != 1 is a where clause, since that is false by definition. Is it possible ids is empty? That might also very much explain the ill-formatted CASE statement, which is the source of the error. Normally, case(dict(a=1, b=2), value=User.name) should result in CASE WHEN name = 'a' THEN 1 WHEN name = 'b' THEN 2 END, which would properly execute.
I tried making a login detail storing program that stores usernames and passwords. I managed to make it work partially where the login manages to recognise the 1st set of login details, however, my login() function cannot seem to recognise the 2nd set of login details that has been appended to the list. Basically, if I append some passwords to the vault list e.g "qwerty", "123456", "2017", it will only accept the 1st password and not the 2nd or 3rd. How do I get the program to accept more login details, not only just one set? Any help would be appreciated.
vault = []
appvault = []
passvault = []
def menu():
mode = input("""Hello {}, below are the modes that you can choose from:\n
##########################################################################
a) Login with username and password
b) Register as a new user
To select a mode, enter the corresponding letter of the mode below
##########################################################################\n
> """).strip()
return mode
def login():
if len(vault) > 0 : #user has to append usernames and passwords before it asks for login details
print("Welcome to the login console")
while True:
username = input ("Enter Username: ")
if username == "":
print("User Name Not entered, try again!")
continue
password = input ("Enter Password: ")
if password == "":
print("Password Not entered, try again!")
continue
try:
for i in vault:
if i[username] == password:
print("Username matches!")
print("Password matches!")
logged() #jumps to logged function and tells the user they are logged on
break
except KeyError: #the except keyerror recognises the existence of the username and password in the list
print("The entered username or password is not found!")
else:
print("You have no usernames and passwords stored!")
def register(): #example where the username is appended. Same applies for the password
print("Please create a username and password into the password vault.\n")
while True:
validname = True
while validname:
username = input("Please enter a username you would like to add to the password vault. NOTE: Your username must be at least 3 characters long: ").strip().lower()
if not username.isalnum():
print("Your username cannot be null, contain spaces or contain symbols \n")
elif len(username) < 3:
print("Your username must be at least 3 characters long \n")
elif len(username) > 30:
print("Your username cannot be over 30 characters \n")
else:
validname = False
validpass = True
while validpass:
password = input("Please enter a password you would like to add to the password vault. NOTE: Your password must be at least 8 characters long: ").strip().lower()
if not password.isalnum():
print("Your password cannot be null, contain spaces or contain symbols \n")
elif len(password) < 8:
print("Your password must be at least 8 characters long \n")
elif len(password) > 20:
print("Your password cannot be over 20 characters long \n")
else:
validpass = False #The validpass has to be True to stay in the function, otherwise if it is false, it will execute another action, in this case the password is appended.
vault.append({username:password})
validinput = True
while validinput:
exit = input("\nEnter 'end' to exit or any key to continue to add more username and passwords:\n> ")
if exit in ["end", "End", "END"]:
break
else:
validinput = False
register()
return register
def logged():
print("----------------------------------------------------------------------\n")
print("You are logged on.")
while True:
chosen_option = menu() #a custom variable is created that puts the menu function into the while loop
if chosen_option in ["a", "A"]:
login()
if chosen_option in ["b", "B"]:
register()
else:
print("""That was not a valid option, please try again:\n """)
You are looping through a list of dicts. Change vault to a dict, and get rid of the for loop:
vault = {}
def login():
if len(vault) > 0 : #user has to append usernames and passwords before it asks for login details
print("Welcome to the login console")
while True:
username = input ("Enter Username: ")
if username == "":
print("User Name Not entered, try again!")
continue
password = input ("Enter Password: ")
if password == "":
print("Password Not entered, try again!")
continue
try:
if vault[username] == password:
print("Username matches!")
print("Password matches!")
logged() #jumps to logged function and tells the user they are logged on
break
except KeyError: #the except keyerror recognises the existence of the username and password in the list
print("The entered username or password is not found!")
else:
print("You have no usernames and passwords stored!")
And you will have to replace the append in register() from
vault.append({username:password})
to
vault[username] = password
On another note, I would suggest not to store the actual passwords, but rather the hashes. Take a look here.
i wanted to insert new data into porstgresql using odooRPc i am having error like below
RPCError: dictionary update sequence element #0 has length 1; 2 is required
my python script code is :
def POST(self):
data = []
web.header('Access-Control-Allow-Origin', '*')
web.header('Access-Control-Allow-Credentials', 'true')
web.header('Content-Type', 'application/json')
auth = web.input()
print("auth")
print(auth)
name=auth['username']
pwd=auth['password']
city=auth['city']
eml=auth['eml']
mobile=auth['phone']
state_id=auth['state']
country_id=auth['country']
# print(type(auth['country']))
# country_id=auth.get('Country').get('id')
# country_id=auth['country'].get('id')
# print(country_id)
# state_id=auth['state']
# print(state_id)
odoo = odoorpc.ODOO('field.holisticbs.com',port=8069)
odoo.login('field.holisticbs.com','info#holisticbs.com','admin')
# Customer = odoo.execute_kw('res.partner','create',{'name':name,' email':eml,'mobile':mobile,' country_id':country_id,'state_id':state_id})
Customer = odoo.execute_kw('res.partner','create',{'name':name,' email':eml,'mobile':mobile})
print(Customer)
# Users = odoo.env['res.partner']
# user = Users.browse([int(idu)])
# print(user)
# Customer = odoo.execute_kw('res.user','create',{'login':eml,' password':pwd})
return json.dumps(Customer)
I have made my comments as below , kindly request you to find it as below it will help in your case:
Well there are many RPC Library (Python) for connecting with the API of Odoo/OpenERP:
xmlrpclib
odoorpc
erppeek
oerplib
openerplib..
In Your case You have chose the odoorpc.
Here is the code snippet for using it odoorpc:
import odoorpc
import json
domain ='localhost' #the domain
port=8069 #the active port
username = 'username' #the user name
password = 'password' #the user password
dbname = 'database_name' #the database
#Validate the credentials
odoo = odoorpc.ODOO(domain, port=port)
odoo.login(dbname, username, password)
#Login User details
user = odoo.env.user
print(user.name) # user name
print(user.company_id.name) # user company name
#Create a partner
user_data = odoo.execute('res.partner', 'create',
{'name':"PRAKASH",'
email':" prakashsharmacs24#gmail.com",
'mobile':"7859884833"})
print(user_data)
But i have also find you are using the method execute_kw so please use xmlrpclib if you want to use method execute_kw
Here is the code snippet for using it xmlrpclib:
import xmlrpclib
domain ='localhost' #the domain
port=8069 #the active port
username = 'username' #the user name
password = 'password' #the user password
dbname = 'database_name' #the database
#Validate the credentials
url='http://{domain}:{port}'.format(domain=domain,port=port)
login_url='{url}/xmlrpc/2/common'.format(url=url)
sock_common = xmlrpclib.ServerProxy(login_url)
uid = sock_common.login(dbname, username, password)
print sock_common.version()
print uid
models = xmlrpclib.ServerProxy('{}/xmlrpc/2/object'.format(url))
#Validate the access rights
print models.execute_kw(dbname, uid, password,
'res.partner', 'check_access_rights',
['read'], {'raise_exception': False})
#Execute the query
print models.execute_kw(dbname, uid, password,
'res.partner', 'search',
[[['is_company', '=', True], ['customer', '=', True]]])
You can also refer this Link for knowing the difference between the RPC library
I hope this will help you ..