How could django model get one field? - django

I know how to get a line,but I don't know how to get one field.
for exmple,there is a table,have id,title,content fields.
ModelsExample.objects.filter(id = showid)# get one line.
how to get title field only?

You can use values or values_list for that matter. Depending on how you would like to use tour context:
Use of values() example:
r = ModelsExample.objects.filter(id=showid).values('title')
This would return something like: [{'title': 'My title'}] so you could access it with r[0]['title'].
Use of values_list() example:
r = ModelsExample.objects.filter(id=showid).values_list('title')
This would return something like: [('My title',)] so you could access it as r[0][0].
Use of values_list(flat=True) example:
r = ModelsExample.objects.filter(id=showid).values_list('title', flat=True)
This would return something like: ['My title'] so you could access it as r[0].
And of course you can always access each field of the model as:
r = ModelsExample.objects.get(id=showid)
r.title

You can get only one field like this
ModelsExample.objects.filter(id = showid).values('title')
https://docs.djangoproject.com/en/1.8/ref/models/querysets/#values

You have two ways:
ModelsExample.objects.filter(id=showid)[0].title
ModelsExample.objects.filter(id=showid).only('title')[0].title
or
ModelsExample.objects.get(id=showid).title
First fetch collection and get first element. If collection don't have elements they raise IndexError.
Second get one element. If in DB You have more elements they raise MultipleObjectsReturned. If cannot found any row, they raise NoResultFound.

Related

Is there any way I can avoid iterating over a query set with single value?

I get a queryset object every time i want some data from models.
So when i say,
"items = Items.object.get(value=value)"
I get --
"<QuerySet [<Item-name>]>"
I have to iterate through the queryset object to get the data and I do that with
"items[0]"
Is there any way I can avoid this?
Edit: I meant "items = Items.object.filter(value=value)"
first of all items = Items.objects.get(value=value) does not return a queryset,
rather it returns an object of <Items: Items object (1)>
To get the first(or just one result) or last date from the object, do this Items.objects.first() or Items.objects.last()
To get the desired data without using its index position, then you can filter it like this Items.objects.filter(value=value)
You are mistaken. items = Items.object.get(value=value) will not give you a queryset, but an object. items = Items.object.filter(value=value)
would give you a queryset.
Filter method will always give you a queryset, because; in order to minimize the need of database hits, django considers you might add additional filters through your code. So if you not execute that queryset, e.g. by using list(your_queryset) django never hits the database.
# when you are using 'get' in your query, you don't need to iterate, directly get an access to the field values
try:
items = Items.object.get(value=value)
except Items.DoesNotExist:
items = None
if items:
print(items.value)

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'])

Select a value in a Django Query

I've a Django Query:-
obj = ABC.objects.filter(column1 = value)
a_list = []
for x in obj:
a_list.append(x.column2)
I want to fetch the list of values of column2 in one go., ie dont want to use the for loop. Is there any 1 straight forward query for this?
ABC.objects.filter(column1=value).values_list('column2', flat=True)
https://docs.djangoproject.com/en/1.6/ref/models/querysets/#values-list
If you don’t pass any values to values_list(), it will return all the fields in the model, in the order they were declared.
Note that this method returns a ValuesListQuerySet. This class behaves like a list. Most of the time this is enough, but if you require an actual Python list object, you can simply call list() on it, which will evaluate the queryset.

How to get a particular attribute from queryset in Django in view?

I have a query like this:
file_s = Share.objects.filter(shared_user_id=log_id)
Now, I want to get the files_id attribute from file_s in Django view. How can I do that?
Use values() to get particular attribute which will return you list of dicts, like
file_s = Share.objects.filter(shared_user_id=log_id).values('files_id')
EDIT: If you want only one attribute then you can use flat=True to suggest to return just list of values. However, make sure in what order the list will be.
file_s = Share.objects.filter(shared_user_id=log_id).values_list('files_id', flat=True).order_by('id')
Your Share.objects.filter() call returns a Djagno QuerySet object which is not a single record, but an iterable of filtered objects from the database with each item being a Share instance. It's possible that your filter call will return more than one item.
You can iterate over the QuerySet using a loop such as:
for share in files_s:
print share.files_id
If you know that your query is only expected to return a single item, you could do:
share = Share.objects.get(shared_user_id=log_id)
which will return a single Share instance from which you can access the files_id attribute. An exception will be raised if the query would return anything other than 1 result.
If you want to get only the value from a single value QuerySet you can do:
file_s = Share.objects.filter(shared_user_id=log_id).values_list('files_id', flat=True).first()

Query of a subquery in Django

I'm trying to do a query from another query, but Django said: 'Caught DatabaseError while rendering: subquery returns more than 1 row.' I'm using PostGis.
my model
class Place(models.Model):
coordinate = models.PointField()
class TranslatedPlace(models.Model):
place = models.ForeignKey(Place)
my view
near_coordinates = Place.objects.filter(coordinate__distance_lte=(place_obj.coordinate, D(km=100)))
near_places = TranslatedPlace.objects.filter(place=near_coordinates)
I believe you'll want to use in to filter the second queryset
near_coordinates = Place.objects.filter(coordinate__distance_lte=(place_obj.coordinate, D(km=100)))
near_places = TranslatedPlace.objects.filter(place__in=near_coordinates)
If Place.objects.filter(coordinate__distance_lte=(place_obj.coordinate, D(km=100))) is SUPPOSED to return multiple objects, you might be able to use near_places = TranslatedPlace.objects.filter(place__in=near_coordinates) note the __in for the place field. If you are only supposed to get one and there IS only one, you could do a .get() instead of .filter(). If there is more than one in the database, but you only want to get one, you could .filter(...)[0] to get the first one. Also, you could .filter(...).order_by('sort_field')[0] if you want to get the first one based on some sorting.