Processing QuerySet result - django

I have the following code to validate user credentials
userDetail = User.objects.using (settings.DATABASE_CONF).filter (status=1, email_id=emailId, password=password).values
('user_id' , 'email_id' )
Im able to validate it and get the result. I want to Print user_id into my console and also set it in session object. I tried
if userDetail :
But it returns true even if the userDetail list is empty.
I tried
for n in userDetail:
It says "'instancemethod' object is not iterable"
How to validate it is empty or null and take the value of user_id?

You can't split a method call before the parentheses. What you have done there is assign userDetail to the method values, not the result. Bring the parens back onto the previous line - if you must split, you can do it after the open paren.

Related

Django update model in shell not saving

I´m trying to update the data of an existing model with a csv. I read the file and assign the values with no problem.
If I try `MyModel.update() everything runs with no error but the data is not saved.
with open('Productosold.csv') as csvfile:
reader = csv.DictReader(csvfile)
for row in reader:
p = ProductosBase.objects.filter(codigo_barra = row['codigo_barra'])
p.region=row['region']
p.producto_ing=row['producto_ing']
p.packaging_ing=row['packaging_ing']
p.precio_compra=row['precio_compra']
p.uom=row['uom']
p.units_inner=row['units_inner']
p.inner_master=row['inner_master']
p.tier=row['tier']
p.precio_lista_internacional=row['precio_lista_internacional']
p.update()
I usualy upload new data using the MyModel.save() method and have no problem.
Now, if I use that I get "Queryset has no attribute save".
p.save()
If I print some of the p.values I can see they are populated correctly from the csv file.
What I´m doing wrong?
Thanks in advance!
.filter always returns a queryset, not a single instance. When you set all those values, you are just setting (previously non-existing) attributes onto that queryset object; you are not setting fields in a model instance. You should use .get to get an instance and save that.
p = ProductosBase.objects.get(codigo_barra = row['codigo_barra'])
p.region=row['region']
...
p.save()
However, since all the columns in your CSV map precisely to fields on the model, you could in fact use filter and update to do the whole thing in one go:
for row in reader:
ProductosBase.objects.filter(codigo_barra=row['codigo_barra']).update(**row)
and no need for any of the rest of the code.
You need filter() whenever you expect more than just one object that matches your criteria. If no item was found matching your criteria, filter() returns am empty queryset without throwing an error.
Also you can use get() but when you expect one (and only one) item that matches your criteria. Get throws an error if the item does not exist or if multiple items exist that match your criteria. You should therefore always use if in a try.. except .. block or with a shortcut function like get_object_or_404 in order to handle the exceptions properly. I'd recommend using get_object_or_404 in this case.
p = get_object_or_404(ProductosBase, codigo_barra=row['codigo_barra'])

Using Django reduce(or_) - How can I store an unmatched query with 0 results in a variable

I have a function that takes a user's input from a list of data and searches my database for any items that matches the user's input, and returns all results that are in my database:
results = results.filter(
reduce(or_, (Q(name__icontains=itm.strip()) for itm in query))
)
I would like to handle cases where the user's input is not present in my database. since results fitlers down to what exists, how can I check if the above code failed to find at least one matching result for a query, and store that query in a variable? For example, if results queried my database for the following list: ['one', 'two', 'thee'], assuming 'thee' is not in my database but the other two are, I would like to store the string "thee" in a variable to use later
You can simply evaluate results as a Boolean:
if not results:
print('No match found.')
From QuerySet's documentation:
bool(). Testing a QuerySet in a boolean context, such as using bool(),
or, and or an if statement, will cause the query to be executed. If
there is at least one result, the QuerySet is True, otherwise False.
For example:
if Entry.objects.filter(headline="Test"):
print("There is at least one Entry with the headline Test")
You can add one query for query:
For example:
query = query.append(Q(name__isnull=True)) or something that always False
Instead of trying to do it one piece of code:
results = results.filter(
reduce(or_, (Q(name__icontains=itm.strip()) for itm in query))
)
I iterated over each item in query and checked if it exists
for each in query:
r = results.filter(name__icontains=each)
if r.exists() == False:
Do something with each
Though not as efficient as I'd like, it solves the problem for now

Filter data from queryset in Django wihtout returning the entire queryset

I'm trying get an attribute from a given object in Djano. I'm getting the value properly but I'm curious as if there is a better way to grab this data.
I'm getting the name attribute by using:
owner_name = Owner.objects.filter(id=id).values('name')
And it properly returns the name attribute I'm looking for, but it is in the form of:
<QuerySet [{'name': u'John Doe'}]>
How can I get it to just return "John Doe" instead of <QuerySet [{'name': u'John Doe'}]>?
Edit: I've found out that I can get the info I need by doing:
owner_name[0].get('name')
and it will return John Doe. Is there a better way to do this still just to get 1 attribute?
You want a values_list query with the flat=True parameter. From the docs:
A common need is to get a specific field value of a certain model instance. To achieve that, use values_list() followed by a get() call:
Entry.objects.values_list('headline', flat=True).get(pk=1)
Or in your case:
Owner.objects.values_list('name', flat=True).get(id=id)
Note that get will raise an exception if there is not exactly one matching result. If that's a possibility, say because you were filtering on something other than id or because there might be no matching object, you could catch the exceptions or you could work with the list of names returned and check its length.

Django Nested Filter Values

This line works and returns the value that I'm looking for:
logs = Log.objects.filter(filterURI=aFilter.uri).values()[0]['yk']
However, when I try to add another filter and do the same I get errors:
logs = Log.objects.filter(filterURI=aFilter.uri).filter(k=k-1).values()[0]['yk']
My understanding is that a object.filter returns a queryset but so does a 'filter of a filter'. So I should be able to do the 'values' call in the same way regardless of whether I have one filter or 1000.
What am I doing wrong here.
Thanks in advance.
I don't think the error is in the fact that you have two filters - it's in the actual second filter. k=k-1 will only work if you have both a model field and a local variable called k - the first is on the left of the expression, the second on the right.
If you want to refer to the model field on the right of the expression, use F:
.filter(k=(F('k')-1)

Output location of images for django-imagekit

I'm trying to output a list of images that belong to each record in my app as below:
pri_photo = vehicle.images.all()[:1]
sec_photos = vehicle.images.all()[1:]
This first part is OK. The part I'm having issues with is when I try
pri_photo.original_image.url
sec_photos.original_image.url
The above two lines of code give me a 'QuerySet' object has no attribute 'original_image'. What could be the issue?
I also want the photos in sec_photos to be output as image1, image2,... upto the last one
[:1] just limits the number of records returned by the queryset, still it is a queryset result, not a single object.
to get a single object, you shoud use
[0]
or
[0:1].get()
but it's not safe, as it will raise an error if none objects match the query. to do it properly, use filter() and if result are present then get(), or
try:
#get()
except modelname.DoesNotExist:
# do shomething else
also, if you are looking for the latest object, maybe you can just use http://www.djangoproject.com/documentation/models/get_latest/