how to get a field name knowing id number in django - django

I have the following query set to get the subcategory name knowing the id number:
query_sc = Post_Sub_Category.objects.filter(id='1').values('sub_category_name')
it gave me the following output:
{'sub_category_name': 'car'}
how can I get only the car? I mean I need the output to be a car only 'the value not the dictionary.

Use values_list instead of values, here's a quote straight 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)
'First entry'

It looks like you're looking for values_list. With values_list you can get only the values, and if you want a flat list you can do the following.
Post_Sub_Category.objects.filter(id='1').values_list('sub_category_name', flat=True)
And the result will be ["car"]

Related

Exclude fields with the same value using Django querysets

In my project, I have Articles and User Responses that have the same value "title". I only want to find the first Articles, because other object have the same "title", these are the users' answers. How can I exclude objects from queryset have the same "title" parameter.
I try this:
q1 = Article.objects.order_by().values('title').distinct()
*works good but it returns something like a list.
Well, I tried to convert it to query:
q2 = Article.objects.filter(title__in=q1).distinct()
*But it causes it to return all Repeat-Topic Articles again.
How to exclude objects from queryset that have the same title without changing them to a list?
On PostgreSQL only, you can pass positional arguments (*fields) in order to specify the names of fields to which the DISTINCT should apply.
If it is your's case then the following must be work:
Article.objects.filter(title__in=q1).order_by('title').distinct('title')

Overwrite field in queryset annotate

I have a django model with the fields name (string) and value (integer). Say I need to return a queryset of {name:..., value:...} objects, with each value doubled. What I am trying to do now is:
queryset.annotate(value=F('value') * 2)
However, django tells me that the field value already exists.
I also tried using extra:
queryset.annotate(value_double=F('value') * 2).extra(select={'value': 'value_double'})
but that also does not work since value_double is not a valid field.
Of course, in this case I could use something like queryset.extra(select={'value': 'value * 2'}), but I have some other, more complicated cases involving a lot of functions where I really don't want to write sql, but I'd rather find a solution in django. Again, in all of my cases, annotate works perfectly fine as long as I give the result a new name.
Say your model is XYZ with fields name and val. If you want val to contain val*2 use below queryset
x = XYZ.objects.values('name').annotate(val=F('val')*2)
print(x)
Result
<QuerySet [{'name': abc, 'val': 104},...............]
If you want queryset that return name,val and doubleval. You can use below query for same.
x = XYZ.objects.values('name','val',doubleval=F('val')*2)
print(x)
Result
<QuerySet [{'name': abc, 'val':52,'doubleval': 104},...............]
Hope this help.

Access to the model element after filtering in the template

I can not access the model field after applying the filter in the template, like this:
{{service_item_v|get_first|first|get_item:'price'.service}}
The problem is that it throws an error:
TemplateSyntaxError at /payment/
Could not parse the remainder: '.service' from 'service_item_v|get_first|first|get_item:'price'.service'
The element finds correctly if you remove the field name from the dot. Also the element has this field, since it gets it if you do not apply the filter.
The question is how to access the field in this case?
You just need to put the result of filtering through "with" under another name. And after that you can access the attributes of the element.
You can't use it on that way, it's not how it works. Because we can't see what your filter doing, I can suggest two things:
Create another filter or add more arguments to your filter get_item:'price,service'
Then in your filter split values:
def get_item(value):
values_list = value.split(",")
# do something with values from the list
create a function in your model instead of template filter and do filtering there.
def get_item(self):
price = # your logic
return price.service
Then in your template just {{ service_item_v.get_item }}

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.

Aggregation and extra values with Django

I have a model which looks like this:
class MyModel(models.Model)
value = models.DecimalField()
date = models.DatetimeField()
I'm doing this request:
MyModel.objects.aggregate(Min("value"))
and I'm getting the expected result:
{"mymodel__min": the_actual_minimum_value}
However, I can't figure out a way to get at the same time the minimum value AND the associated date (the date at which the minimum value occured).
Does the Django ORM allow this, or do I have to use raw SQL ?
What you want to do is annotate the query, so that you get back your usual results but also have some data added to the result. So:
MyModel.objects.annotate(Min("value"))
Will return the normal result with mymodel__min as an additional value
In reply to your comment, I think this is what you are looking for? This will return the dates with their corresponding Min values.
MyModel.objects.values('date').annotate(Min("value"))
Edit: In further reply to your comment in that you want the lowest valued entry but also want the additional date field within your result, you could do something like so:
MyModel.objects.values('date').annotate(min_value=Min('value')).order_by('min_value')[0]
This will get the resulting dict you are asking for by ordering the results and then simply taking the first index which will always be the lowest value.
See more