Django: Get one key and value from queryset dictionary - python

I have this query:
item = Item.objects.filter(id=3)
It is returning a queryset with its the keys and values.
Now I need to extract a particular value from the queryset, like this:
item_name = item['name']
But it does not work. How can I achieve this? Send the most simple way if possible, please. Thanks!

You have several wrong assumptions here.
A queryset is not a dict and does not have keys and values. It's a sequence of items, if anything most similar to a list.
I think what you want to do is to get a specific instance from the database, and access its fields. To get one instance you use get, not filter, as filter will always give you a queryset even if there is only a single match. Then, from that instance, you use attribute access not dict lookup. So:
item = Item.objects.get(id=3)
item_name = item.name

Here you can use the getattr function of python through which you can get your objective.
getattr(item, 'name')

Related

Get a single value from user database django

im new on django, and i want to get a single value from a queryset, te query would be something like this:
select last_task from User where user_id=1
I tried with values() and only() but it doesnt work.
worker = request.user
Worker.objects.filter(user=worker.id).values("last_board")
values() return me a dictionary and i cant extract the single value from it to use.
You're probably looking for values_list, in particular with flat=True. https://docs.djangoproject.com/en/3.2/ref/models/querysets/#django.db.models.query.QuerySet.values_list
worker = request.user
Worker.objects.filter(user=worker.id).values_list("last_board", flat=True)
This will return a flat list of "last_board" values. If there is only one value, then it will return the single value. If there are multiple, it will return a list of values (no dict or unnecessary tuple).

Django - calling attribute from queryset with a string

I'm trying to loop over different query sets while not repeating myself too much and have encountered a problem using the queryset class.
This is not necessarily completely a Django-problem.
What I'm trying to do is to use my keylist, which corresponds to a django model's column names, to create a list of the data from those column names, what i want to do is something like this:
if needthisdata==1:
needdata=['column1', 'column2', 'column3']
else:
needdata=['column1', 'column4', 'column7']
entry=djangomodel.get.all().filter(identifier='id')
dictitems=[]
for n in range(0, len(needdata)):
if n==0:
dictitems=[entry.needdata[n]]
else:
dictitems.append(entry.needdata[n])
Which of course doesn't work since the queryset doesn't have a need data attribute, is there some way to call an attribute for a class with a string in this way?
A valid Django statement to obtain a single entry
First of all, there are some semantical problems here:
itentifier should probably be identifier, id, or pk;
you use .all immedately instead of first obtaining a manager (probably .objects); and
you here use a .filter(..) on the queryset to filter on an identifier, but usually this should be a .get(..), since by using a filter, zero, one or more results can be returned in an iterable.
entry = djangomodel.objects.get(id=some_id)
So now we obtain a single entry, but that of course does not resolve
obtaining the columns.
If all elements are real Django columns
In case the columns are real Django fields (so no #propertys, etc.) then we can use values_list, and perform a list(..) constructor on it:
dictitems = list(djangomodel.objects.values_list(*needdata).get(id=some_id))
If case some elements are #propertys
In case not all those fields are real Django fields, then we can use attrgetter instead:
from operator import attrgetter
dictitems = list(attrgetter(*needdata)(djangomodel.objects.get(id=some_id)))

How to find not null variables from URL query string? or can we get the variable in URL query string from request in python

I want to filter data based on multiple fields in Django python. The scenario is, if a GET request to webserver comes as /searchStudent/?firstName=&lastName=xyzage=23&class=&city= and we dont know what can be the possible parameter in query string, some of them can come with value and some variable doesnot comes with value. The question is, is there any to get the variable which have only value or which dont have values from request. I know we can simply getting value by using request.GET.get('city') but I am finding way for getting the non null variable from query string, is there any way to find the non value variable from query string? In above scenario city, class, and firstName doesn't have values and I dont want to add it on filter. what will be the right approach? please suggest the right way.
To get a dict of non-empty query parameters use this code:
non_empty_params = dict((field, value)
for field, value in request.GET.iteritems() if value)
But do not build queryset this way. You should never ever trust data from the user input. So you have to have a list of fields to search and use this list to filter out incorrect field names:
fields = ('firstName', 'lastName', 'age', 'class', 'city', )
filter_params = dict((field, value)
for field, value in request.GET.iteritems()
if value and field in fields)
students = Student.objects.filter(**filter_params)
I did this way and I get answer for filtering dynamically
filter_args={}
if request.GET.get('firstName') :
filter_args['firstName']=request.GET.get('firstName')
if request.GET.get('lastName') :
filter_args['lastName']=request.GET.get('lastName')
if request.GET.get('city') :
filter_args['city']=request.GET.get('city')
Student.object.filter(**filter_args)
This is know as Dynamic Queries, I was not aware with this. Thanks #catavaran, for suggesting concept. also refered this link Dynamic Django Queries

querying a array in django

idarr = [1,2,3,4,5]
for i in range(len(idarr)):
upload.objects.filter(idarr[i])
Cant we pass the idarr at one shot to the query
I am assuming that you are trying to filter all instances of Upload whose id is in the list idarr. If that is the case then you can go about it like this:
Upload.objects.filter(id__in = idarr)
Read the documentation for more details.
So much wrong in so few lines...
In Python, never loop through range(len(whatever)). Just do for i in whatever.
Assuming upload is a Django model, you can't just pass a value to filter - you need to say what you're filtering against. Presumably it's the primary key, so you want .filter(pk=i).
If you want to filter against any of the values in a list, use __in: .filter(pk__in=idarr).

Django models - how to filter out duplicate values by PK after the fact?

I build a list of Django model objects by making several queries. Then I want to remove any duplicates, (all of these objects are of the same type with an auto_increment int PK), but I can't use set() because they aren't hashable.
Is there a quick and easy way to do this? I'm considering using a dict instead of a list with the id as the key.
In general it's better to combine all your queries into a single query if possible. Ie.
q = Model.objects.filter(Q(field1=f1)|Q(field2=f2))
instead of
q1 = Models.object.filter(field1=f1)
q2 = Models.object.filter(field2=f2)
If the first query is returning duplicated Models then use distinct()
q = Model.objects.filter(Q(field1=f1)|Q(field2=f2)).distinct()
If your query really is impossible to execute with a single command, then you'll have to resort to using a dict or other technique recommended in the other answers. It might be helpful if you posted the exact query on SO and we could see if it would be possible to combine into a single query. In my experience, most queries can be done with a single queryset.
Is there a quick and easy way to do this? I'm considering using a dict instead of a list with the id as the key.
That's exactly what I would do if you were locked into your current structure of making several queries. Then a simply dictionary.values() will return your list back.
If you have a little more flexibility, why not use Q objects? Instead of actually making the queries, store each query in a Q object and use a bitwise or ("|") to execute a single query. This will achieve your goal and save database hits.
Django Q objects
You can use a set if you add the __hash__ function to your model definition so that it returns the id (assuming this doesn't interfere with other hash behaviour you may have in your app):
class MyModel(models.Model):
def __hash__(self):
return self.pk
If the order doesn't matter, use a dict.
Remove "duplicates" depends on how you define "duplicated".
If you want EVERY column (except the PK) to match, that's a pain in the neck -- it's a lot of comparing.
If, on the other hand, you have some "natural key" column (or short set of columns) than you can easily query and remove these.
master = MyModel.objects.get( id=theMasterKey )
dups = MyModel.objects.filter( fld1=master.fld1, fld2=master.fld2 )
dups.all().delete()
If you can identify some shorter set of key fields for duplicate identification, this works pretty well.
Edit
If the model objects haven't been saved to the database yet, you can make a dictionary on a tuple of these keys.
unique = {}
...
key = (anObject.fld1,anObject.fld2)
if key not in unique:
unique[key]= anObject
I use this one:
dict(zip(map(lambda x: x.pk,items),items)).values()

Categories