Multiple arguments in MySQL raw() query in DJango-Python - python

I need to find a person when he enters his mobile number or email in the login form.
My raw() query goes like this:
user = Users.objects.raw('SELECT * FROM main_users WHERE mobile = %s OR email = %s',[login_id],[login_id])
But I am always getting a error:
Exception Value: not enough arguments for format string
So, what's the correct format for getting this solved?

You should put parameters under the same list:
user = Users.objects.raw('SELECT * FROM main_users WHERE mobile = %s OR email = %s',
[mobile, email])

There is no need for a raw query here.
users = User.objects.filter(Q(mobile=login_id) | Q(email=login_id))

You can do this by any of these two ways as already said above:
from django.db.models import Q
users = User.objects.filter(Q(mobile=login_id) | Q(email=login_id))
or by using raw() method:
user = Users.objects.raw('SELECT * FROM main_users WHERE mobile = %s OR email = %s',[login_id,login_id])

The upper solutions were not working for me. I solved by this in Python 3
user = Users.objects.raw("SELECT * FROM main_users WHERE mobile = '%s' OR email = '%s' " %(mobile, email))

Related

1064 SQL You have an error in your SQL syntax; Python List to String Convert?

I'm still new to coding and sql, and I am working on a library management database system as a project.
And I keep getting a 1064 when trying to store my information in my database.
I'm pretty sure it's trying to tell me that the authors are Lists, and need to be a string, but I'm not sure how to do that, and if I can without query entries!
below is the def in question!
def googleAPI(self):
lineTitle = str(titleInfo.text())
# create getting started variables
api = "https://www.googleapis.com/books/v1/volumes?q=isbn:"
isbn = lineTitle.strip()#input("Enter 10 digit ISBN: ").strip()
# send a request and get a JSON response
resp = urlopen(api + isbn)
# parse JSON into Python as a dictionary
book_data = json.load(resp)
# create additional variables for easy querying
volume_info = book_data["items"][0]["volumeInfo"]
author = volume_info["authors"]
# practice with conditional expressions!
prettify_author = author if len(author) > 1 else author[0]
# display title, author, page count, publication date
# fstrings require Python 3.6 or higher
# \n adds a new line for easier reading
gTitle = str(volume_info['title'])
pCount = str(volume_info['pageCount'])
pubDate = str(volume_info['publishedDate'])
author = str(volume_info["authors"])
prettify_author = author if len(author) > 1 else author[0]
stringAuthor = str(prettify_author)
insertBooksF = "insert into "+bookTable+" values('"+isbn+"','"+gTitle+"','"+stringAuthor+"','"+pubDate+"','"+pCount+"')"
try:
cur.execute(insertBooksF)
con.commit()
print("You failed at failing")
except:
print("You actually failed")
print(f"\nTitle: {volume_info['title']}")
print(f"Author: {prettify_author}")
print(f"Page Count: {volume_info['pageCount']}")
print(f"Publication Date: {volume_info['publishedDate']}")
print("\n***\n")
I believe this line is the one needed adjusting
insertBooksF = "insert into "+bookTable+" values('"+isbn+"','"+gTitle+"','"+stringAuthor+"','"+pubDate+"','"+pCount+"')"
You should ALWAYS let the database connector substitute your field values. Otherwise, you open yourself up to SQL injection, where a malicious user provides a field value like "; delete * from table;
stringAuthor = author if isinstance(author,str) else author[0]
insertBooksF = "insert into "+bookTable+" values(?,?,?,?,?)"
cur.execute(insertBooksF, (isbn, gTitle, stringAuthor, pubDate, pCount))

Django ORM multiple distinct and order by

I work on a simple chat app. I need to query db for an user to get last message of user conversation to other users. Same as main page of whatsapp and telegram.
Model:
class CHAT(models.Model):
sender_uid = models.CharField(max_length=150, db_index=True)
receiver_uid = models.CharField(max_length=150, db_index=True)
message = models.TextField(verbose_name='Message Text')
created = models.IntegerField(default=created_time_epoch)
I tried this query:
message_list = self.model.objects.filter(Q(sender_uid=user_uid)|Q(receiver_uid=user_uid)).order_by('receiver_uid', 'sender_uid', '-created').distinct('receiver_uid', 'sender_uid')
Output:
<QuerySet [<CHAT: ted#ted.com Message: hello 4 To: saeed#saeed.com>, <CHAT: marshal#marshal.com Message: hello6 To: saeed#saeed.com>, <CHAT: saeed#saeed.com Message: hello 5 To: ted#ted.com>]>
My problem is I get two last message from each conversation (if both user send message to each other), In one of them user is sender and in other one user is receiver.
For now I handle it with below code:
message_send_list = list(self.model.objects.filter(sender_uid=user_uid).order_by('receiver_uid', '-created').distinct('receiver_uid'))
message_receive_list = list(self.model.objects.filter(receiver_uid=user_uid).order_by('sender_uid', '-created').distinct('sender_uid'))
temp_list = []
for s_message in message_send_list:
r_message = next((item for item in message_receive_list if item.sender_uid == s_message.receiver_uid), None)
if r_message is not None:
message_receive_list.pop(message_receive_list.index(r_message))
if s_message.created > r_message.created:
temp_list.append(s_message)
else:
temp_list.append(r_message)
else:
temp_list.append(s_message)
temp_list.extend(message_receive_list)
Output:
[<CHAT: saeed#saeed.com Message: hello 5 To: ted#ted.com>, <CHAT: marshal#marshal.com Message: hello6 To: saeed#saeed.com>]
My question is how can I get this result in one query? Problem is user can be sender and receiver of message and I can't distinguish which one is last message of conversation. How to filter or distinct on that?
Based on the description of the problem, you make it a bit too complex. You can obtain the other person with a conditional expression [Django-doc]. So by first making a "reduction" where we take the other person, we can then use a uniqueness filter for that:
from django.db.models import Case, F, When
last_messages = self.model.objects.filter(
Q(sender_uid=user_uid) | Q(receiver_uid=user_uid)
).annotate(
other=Case(
When(sender_uid=user_uid, then=F('receiver_uid')),
default=F('sender_uid'),
output_field=CharField()
)
).order_by('other', '-created').distinct('other')
Furthermor all Chat objects will have an extra attribute: other that thus contains the non-user_uid side.

Trying to Query on Login and based on email and password return First Name

I a have a SQLite Database with:
first_name email password
Andrew t#t.com abcde
I am using this to check if there is a matching email and password:
if User.userManager.filter(email = postData['email'], password =
postData['password']):
name = User.userManager.filter(email = postData['email'], password = postData['password'])
print name.get('first_name')
return "success"
When I try to print first_name from the query i did above I get error 'too many values to unpack'
This is happening because get() method expecting for keyword arguments:
https://docs.djangoproject.com/en/1.11/ref/models/querysets/#get
The QuerySet returned by filter() method could contain more than one entry:
https://docs.djangoproject.com/en/1.11/ref/models/querysets/#filter
, so you should specify expected value for the requested field.
One of the ways to access this value is:
print name.get(first_name='Andrew').first_name
On the other hand, you could limit your filter query:
User.userManager.filter(email = postData['email'], password = postData['password'])[:1]
Or just use get() method straightway and access field value directly:
user = User.userManager.get(email = postData['email'], password = postData['password'])
print user.first_name

NDB query using filters on Structured property which is also repeated ?

I am creating a sample application storing user detail along with its class information.
Modal classes being used are :
Model class for saving user's class data
class MyData(ndb.Model):
subject = ndb.StringProperty()
teacher = ndb.StringProperty()
strength = ndb.IntegerProperty()
date = ndb.DateTimeProperty()
Model class for user
class MyUser(ndb.Model):
user_name = ndb.StringProperty()
email_id = ndb.StringProperty()
my_data = ndb.StructuredProperty(MyData, repeated = True)
I am able to successfully store data into the datastore and can also make simple query on the MyUser entity using some filters based on email_id and user_name.
But when I try to query MyUser result using filter on a property from the MyUser modal's Structured property that is my_data, its not giving correct result.
I think I am querying incorrectly.
Here is my query function
function to query based upon the repeated structure property
def queryMyUserWithStructuredPropertyFilter():
shail_users_query = MyUser.query(ndb.AND(MyUser.email_id == "napolean#gmail.com", MyUser.my_data.strength > 30))
shail_users_list = shail_users_query.fetch(10)
maindatalist=[]
for each_user in shail_users_list:
logging.info('NEW QUERY :: The user details are : %s %s'% (each_user.user_name, each_user.email_id))
# Class data
myData = each_user.my_data
for each_my_data in myData:
templist = [each_my_data.strength, str(each_my_data.date)]
maindatalist.append(templist)
logging.info('NEW QUERY :: The class data is : %s %s %s %s'% (each_my_data.subject, each_my_data.teacher, str(each_my_data.strength),str(each_my_data.date)))
return maindatalist
I want to fetch that entity with repeated Structured property (my_data) should be a list which has strength > 30.
Please help me in knowing where I am doing wrong.
Thanks.
Queries over StructuredProperties return objects for which at least one of the structured ones satisfies the conditions. If you want to filter those properties, you'll have to do it afterwards.
Something like this should do the trick:
def queryMyUserWithStructuredPropertyFilter():
shail_users_query = MyUser.query(MyUser.email_id == "napolean#gmail.com", MyUser.my_data.strength > 30)
shail_users_list = shail_users_query.fetch(10)
# Here, shail_users_list has at most 10 users with email being
# 'napolean#gmail.com' and at least one element in my_data
# with strength > 30
maindatalist = [
[[data.strength, str(data.date)] for data in user.my_data if data.strength > 30] for user in shail_users_list
]
# Now in maindatalist you have ONLY those my_data with strength > 30
return maindatalist

Retrieve gtalk nickname in python xmpp

In python xmpp module, I'm able to retrieve the nickname of any contacts as follows:
self.connection.auth(userJid.getNode(), self.password)
self.roster = self.connection.getRoster()
name = self.roster.getName(buddyJid)
..where buddyJid is of the form user#gmail.com.
Now, I need to retrieve the nickname of the user who authenticates the connection (userJid). I cannot find the name using the above method.
Which method can I use retrieve the name of the current user?
This information is not in the roster. You will need to query the clients individually and get their vCard by sending this IQ :
<iq from='stpeter#jabber.org/roundabout'
id='v1'
type='get'>
<vCard xmlns='vcard-temp'/>
</iq>
Thank you nicholas_o, this is a sample function I put together based your suggestion. (The XML logic isn't ideal, but it was sufficient for the simple task I needed this for)
def vcard(disp, jid):
msg = xmpp.protocol.Iq()
msg.setType('get')
msg.setTo(jid)
qc = msg.addChild('vCard')
qc.setAttr('xmlns', 'vcard-temp')
rep = disp.SendAndWaitForResponse(msg)
# to see what other fields are available in the XML output:
# print rep
userid=fname=lname=title=department=region=None
for i in rep.getChildren():
for j in i.getChildren():
if j.getName() == "TITLE":
title = j.getData().encode('utf-8')
for k in j.getChildren():
if k.getName() == "GIVEN":
fname = k.getData().encode('utf-8')
if k.getName() == "FAMILY":
lname = k.getData().encode('utf-8')
if k.getName() == "ORGUNIT":
department = k.getData().encode('utf-8')
if k.getName() == "REGION":
region = k.getData().encode('utf-8')
return fname, lname, title, department, region

Categories

Resources