I have a model, for example:
class Person(models.Model):
name =
surname =
city =
cars =
I need to get a list of the IDs (primary key auto-set) of the 5 users with the highest number of "cars" with a specific name.
I thought I could do something like:
list = Person.objects.filter(name=name,)('-reputation')[5].id
To get a list of the 5 users with the highest number you can use:
list = Person.objects.filter(name=name).order_by('-reputation')[:5]
to get the ID of each you can use for loop:
for user in list:
userID = user.id
You seem to have missed out the call to order_by.
Person.objects.filter(name=name).order_by('-reputation')[5].id
Using the values_list queryset function can reduce this to a single simple line:
Person.objects.values_list('id', flat=True).filter(name=name).order_by('-reputation')[:5]
and will avoid needing to loop.
Related
I have the list of ids
id_list = [1,2,3,4]
I am using for loop to fetch the result
roles = []
for id in id_list:
roles.append(Role.objects.filter(id = id).values('id' , 'name'))
This give me the result but in this form:
roles = [[{id:1, name:employee}], [{id:2, name=staff}], [{id:3,name=driver}] , [{id:4, name=staffboy}]]
But I want data in a dictionary so that also relatable for JSON response
roles = [{id:1,name:employee} , {id:2,name:staff} , {id:3,name:driver} , {id:4,name:staffboy}]
Any other method of fetching the list of results in a format I want?
Thanks for your help
You can achieve this even without the for loop, you can try something like below -
roles = Role.objects.filter(id__in=[1,2,3,4]).values('id' , 'name')
Make sure its a double underscore.
But this will not be a python list. roles would be a QuerySet. You can convert to python list like below -
list(roles)
you can use extend instead of append.
roles = []
for id in id_list:
roles.extend(Role.objects.filter(id=id).values("id", "name"))
I have a database where data is organized by a number that is unique, and a name that isn't unique. for example:
NumCOL: NameCOL:
1 Jay
2 Joel
3 Joey
4 Joel
Could I use a filter and get statement to grab names where the number is equal to a certain number? Let's say I have a form that lets a user pick a number from the database and the user picks the number 2.
num = request.POST.get('FormNumber') #num = 2
name = Database.objects.filter(NumCOL=num).get('NameCOL')
return HttpResponse(name)
Can something like this be done? I want to grab the name wherever the user selects based on their number. Based on the code I should get a response Joel.
Thanks for your help!
name = Database.objects.get(NumCOL=num)
#name = Database.objects.filter(NumCOL=num)
return HttpResponse(name.NameCOL)
As pointed by daniel in the comments and by metmirr in his answer, you don't need to do it like this. The following works just fine.
name = Database.objects.get(NumCOL=num)
return HttpResponse(name.NameCOL)
Retrieving all the fields of a single model does not add any overhead whatsoever to the query. Get is used to retrieve a single row and not a single column.
To retrieve a single column, you can do:
name = Database.objects.filter(NumCOL=num).values('NameCol')
To retrieve a single cell you can do
name = Database.objects.filter(NumCOL=num).values_list('NameCol', flat=True)
As a side note, by convention we name the model with the first letter in upper case and fields are all lower case.
I'm assigning values into a dictionary like this:
contacts = dict()
for company in companies_query:
contacts[company.id] = dict()
for contact in contacts_query:
contacts[contact.company_id][contact.id] = contact
So, for example I now have this key in the contacts dictionary contacts["15"]["10"] assuming there's a company with ID of 15 and a contact with ID of 10.
Now I need to create another for loop to add additional data to these contacts.
for sale in sales_query:
contact = contacts[sale.company][sale.contact]
contact.sale_count += 1
contacts[sale.company][sale.contact] = contact
This doesn't work. For the second line it says there's a KeyError with a value of <Contact: Contact object>. sale.company is in this example 15, and the sale.contact is 10.
How do I edit the dictionary objects?
You are passing in the whole Contact() instance object, not the id attribute value of that object. You probably meant to use:
for sale in sales_query:
contact = contacts[sale.company][sale.contact.id]
e.g. use the sale.contact.id attribute rather than use sale.contact directly.
Since you are manipulating the Contact() instance directly you don't need to assign back to the nested dictionary; the following 3 lines should suffice:
for sale in sales_query:
contact = contacts[sale.company][sale.contact.id]
contact.sale_count += 1
Note that using dict() to create an empty dictionary is not really common or idiomatic. Use the {} literal notation instead:
contacts = {}
for company in companies_query:
contacts[company.id] = {}
for contact in contacts_query:
contacts[contact.company_id][contact.id] = contact
You can build the contacts mapping with a dictionary comprehension too:
contacts = {company.id for company in companies_query}
for contact in contacts_query:
contacts[contact.company_id][contact.id] = contact
I have queryset of people:
people = Person.objects.all()
and I have a list un_people = [] - meaning a list of people with unique name.
So, there can be more than one person with the same name. i want to filter for this and then insert into list so that list only contains person objects with unique name.
I tried:
for person in people:
if person.name in un_people:
#... ?
but in list, there are objects, not names. how can I check for objects with same name and then insert into list?
Use a dict to do the uniqueness, then take the values, eg:
uniq_names = {person.name:person for person in people}
uniq_people = uniq_names.values() # use list(unique_names.values()) for Py 3.x
You can use set data structure:
un_people = set(people)
If your elements are not hashable as, JonClemens, suggests you can build a list of names first:
un_people = set([p.name for p in people])
Problem: I need to output the TOP X Contributors determined by the amount of messages posted.
Data: I have a collection of the messages posted. This is not a Database/SQL question by the sample query below just give an overview of the code.
tweetsSQL = db.GqlQuery("SELECT * FROM TweetModel ORDER BY date_created DESC")
My Model:
class TweetModel(db.Model):
# Model Definition
# Tweet Message ID is the Key Name
to_user_id = db.IntegerProperty()
to_user = db.StringProperty(multiline=False)
message = db.StringProperty(multiline=False)
date_created = db.DateTimeProperty(auto_now_add=False)
user = db.ReferenceProperty(UserModel, collection_name = 'tweets')
From examples on SO, I was able to find the TOP X Contributors by doing this:
visits = defaultdict(int)
for t in tweetsSQL:
visits[t.user.from_user] += 1
Now I can then sort it using:
c = sorted(visits.iteritems(), key=operator.itemgetter(1), reverse=True)
But the only way now to retrieve the original Objects is to loop through object c, find the KeyName and then look in TweetsSQL for it to obtain the TweetModel Object.
Is there a better way?
*** Sorry I should have added that Count(*) is not available due to using google app engine
[EDIT 2]
In Summary, given a List of Messages, how do I order them by User's message Count.
IN SQL, it would be:
SELECT * FROM TweetModel GROUP BY Users ORDER BY Count(*)
But I cannot do it in SQL and need to duplicate this functionality in code. My starting point is "SELECT * FROM TweetModel"
Use heapq.nlargest() instead of sorted(), for efficiency; it's what it's for. I don't know the answer about the DB part of your question.
I think your job would be a lot easier if you change the SQL query to something like:
SELECT top 100 userId FROM TweetModel GROUP BY userId ORDER BY count(*)
I wouldn't bother with the TweetModel class if you only need the data to solve the stated problem.
Why not invert the dictionary, once you have constructed it, so that the keys are the message counts and the values are the users? Then you can sort the keys and easily get to the users.