Check if object T exists field-wise in queryset of T - django

I have an address objects in my app which has the usual street, street_nr, etc. fields.
Is there a better way to do this:
Address.objects.filter(street=data["street"],
street_nr=data["street_nr"],
zip_code=data["zip_code"],
city_name=data["city_name"],
country_name=data["country_name"]).exists()
Mind that I check only for the passed fields.

As long as the key names in the data dictionary match the field names you want to query on, you can use the **kwargs syntax:
Address.objects.filter(**data)

Related

Change one django form field value relative to another

Let say I have two fields in a django form country and state.I want the values of state to relatively change with the values of country.i.e. I want the state field to list out the states of the country that user has selected. Also the state field should be empty during form initiation.I know that this can be done using java script and other scripts.But,I would like to know if there are any conventional methods exists in django to do the same.???
Sounds like you need to create a model for Country and State.
State model should have a foreign key linking to Country. This means many states can be related to one country. Then, populate the tables with all countries and states you want.
In your form, you can override the 'init' method with custom behavior. So, if you have declared a field 'state' then you can do something like self.fields['state'].choices = State.object.filter(country_id=some_country_id). This assumes you have some_country_id already and you can pass this through as a kwarg during instantiation.

Query Django's HStoreField values using LIKE

I have a model with some HStoreField attributes and I can't seem to use Django's ORM HStoreField to query those values using LIKE.
When doing Model.objects.filter(hstoreattr__values__contains=['text']), the queryset only contains rows in which hstoreattr has any value that matches text exactly.
What I'm looking for is a way to search by, say, te instead of text and those same rows be returned as well. I'm aware this is possible in a raw PostgreSQL query but I'm looking for a solution that uses Django ORM.
If you want to check value of particular key in every object if it contains 'te', you can do:
Model.objects.filter(hstoreattr__your_key__icontains='te')
If you want to check if any key in your hstore field contains 'te', you will need to create your own lookup in django, because by default django won't do such thing. Refer to custom lookups in django docs for more info.
As far as I can remember, you cannot filter in values. If you want to filter in values, you have to pass a column and value you are referencing to. When you want it to be case insensitive use __icontains.
Although you cannot filter by all values, you can filter by all keys. Just like you showed in your code.
If you want to search for 'text' in all objects in key named let's say 'fo' - just do smth like this:
Model.objects.filter(hstoreattr__icontains={'fo': 'text'})

Django annotate a field value to queryset

I want to attach a field value (id) to a QS like below, but Django throws a 'str' object has no attribute 'lookup' error.
Book.objects.all().annotate(some_id='somerelation__id')
It seems I can get my id value using Sum()
Book.objects.all().annotate(something=Sum('somerelation__id'))
I'm wondering is there not a way to simply annotate raw field values to a QS? Using sum() in this case doesn't feel right.
There are at least three methods of accessing related objects in a queryset.
using Django's double underscore join syntax:
If you just want to use the field of a related object as a condition in your SQL query you can refer to the field field on the related object related_object with related_object__field. All possible lookup types are listed in the Django documentation under Field lookups.
Book.objects.filter(related_object__field=True)
using annotate with F():
You can populate an annotated field in a queryset by refering to the field with the F() object. F() represents the field of a model or an annotated field.
Book.objects.annotate(added_field=F("related_object__field"))
accessing object attributes:
Once the queryset is evaluated, you can access related objects through attributes on that object.
book = Book.objects.get(pk=1)
author = book.author.name # just one author, or…
authors = book.author_set.values("name") # several authors
This triggers an additional query unless you're making use of select_related().
My advice is to go with solution #2 as you're already halfway down that road and I think it'll give you exactly what you're asking for. The problem you're facing right now is that you did not specify a lookup type but instead you're passing a string (somerelation_id) Django doesn't know what to do with.
Also, the Django documentation on annotate() is pretty straight forward. You should look into that (again).
You have <somerelation>_id "by default". For example comment.user_id. It works because User has many Comments. But if Book has many Authors, what author_id supposed to be in this case?

Use GET parameters as query filters

I have a URL with parameters such as:
field1__lt=7&field2__contains=bar
I understand how to get these values from the cleaned_data dict, but how can I put them into filter() statements? filter doesn't seem to like the key being a string.
This is for trusted users only, so there are no security concerns.
Use dict unpacking. If you have a dict like {'field1__lt':7, 'field2__contains':'bar'} in a variable lookups, then you can write filter(**lookups).
I think you need to pass few arguments in .filter method? Then you will need to use Q objects. So, something like this will work correctly.
MyModel.objects.filter(Q(field1__lt=7)&Q(field2__contains=bar))

Django Autoselect Foreign Key Value

I have a model that contains a foreign key value, then in the form generated from this model, I want to auto select the record's key according to the record I'm adding the form's contents to...I've tried the below code, but it tells me QuerySet doesn't contain vehicle
stock = Issues.objects.filter(vehicle=id)
form = IssuesForm(initial={'id_vehicle': stock.vehicle})
I'm a bit new to django btw so any ideas are highly appreciated
filter always gives a QuerySet, which is a set of values. If you just want a single object, you should use get.
However I don't really understand why you need to do the lookup at all. You have the id value already, since you are using it to look up stock. So why don't you just pass id as the value for id_vehicle?