Django - get queryset with id's not in set of values - django-models

According to doc -
https://docs.djangoproject.com/en/dev/topics/db/queries/#the-pk-lookup-shortcut -
I can get set of objects with specified in list ids. Is there any short way to get another set of objects, with id's not in the specified list. Blog.objects.filter(pk__not_in=[1,4,7]) - did not work for me. PS: is there any annotation of possible expresissions for filtering querysets, of making own short expressions?

Use the exclude method.
Blog.objects.exclude(pk__in=[1,4,7])

At first your query is wrong. You should write your query Blog.objects.filter(pk__in=[1,4,7]). And if you want to use not then you should read here

Related

How to filter based on the last element in ArrayField in django

I'm using postgresql database which allows having an array datatype, in addition django provides PostgreSQL specific model fields for that.
My question is how can I filter objects based on the last element of the array?
class Example(models.Model):
tags = ArrayField(models.CharField(...))
example = Example.objects.create(tags=['tag1', 'tag2', 'tag3']
example_tag3 = Example.objects.filter(tags__2='tag3')
I want to filter but don't know what is the size of the tags. Is there any dynamic filtering something like:
example_tag3 = Example.objects.filter(tags__last='tag3')
I don't think there is a way to do that without "killing the performance" other than using raw SQL (see this). But you should avoid doing things like this, from the doc:
Tip: Arrays are not sets; searching for specific array elements can be
a sign of database misdesign. Consider using a separate table with a
row for each item that would be an array element. This will be easier
to search, and is likely to scale better for a large number of
elements.
Adding to the above answer and comment, if changing the table structure isn't an option, you may filter your query based on the first element in an array by using field__0:
example_tag3 = Example.objects.filter(tags__0='tag1')
However, I don't see a way to access the last element directly in the documentation.

Compound sort not working in Spring mongodb

I have a requirement where the records will be sorted based on created date first and if created dates are same, we will sort on another field called as ratings.
In my Spring mongo project I am doing the following thing:
Query query = new Query();
query.with(new Sort(Direction.DESC, "crDate")).with(new Sort(Direction.DESC, "ratings"));
For some reasons its only sorting on the first field ie crDate. And if both dates are same, sort by ratings never work.
When i try to check the value of sort object it shows me this:
{"crDate":-1,"ratings":-1}
Another finding is, mongo takes in the following syntax for compound sorts:
db.abc.find({..some criteria..}).sort([["crDate",-1],["ratings",-1]]);
Is this a bug in spring mongodb implementation or I missed something?
Looking at the Spring API Documentation it shows you can specify multiple strings to the sort object you are creating in a list. From you snippet above I would suggest you need to only apply the one sort object that takes the two fields, something like
query.with(new Sort(Direction.DESC, Arrays.asList("crDate", "ratings")));
There was another constructor that took the List of Order objects. Strange but I tried it with that now and it seems to be working.
I am now using a single with clause and passing in a List of Order

BadArgumentError: _MultiQuery with cursors requires __key__ order in ndb

I can't understand what this error means and apparently, no one ever got the same error on the internet
BadArgumentError: _MultiQuery with cursors requires __key__ order
This happens here:
return SocialNotification.query().order(-SocialNotification.date).filter(SocialNotification.source_key.IN(nodes_list)).fetch_page(10)
The property source_key is obviously a key and nodes_list is a list of entity keys previously retrieved.
What I need is to find all the SocialNotifications that have a field source_key that match one of the keys in the list.
The error message tries to tell you you that queries involving IN and cursors must be ordered by __key__ (which is the internal name for the key of the entity). (This is needed so that the results can be properly merged and made unique.) In this case you have to replace your .order() call with .order(SocialNotification._key).
It seems that this also happens when you filter for an inequality and try to fetch a page.
(e.g. MyModel.query(MyModel.prop != 'value').fetch_page(...) . This basically means (unless i missed something) that you can't fetch_page when using an inequality filter because on one hand you need the sort to be MyModel.prop but on the other hand you need it to be MyModel._key, which is hard :)
I found the answer here: https://developers.google.com/appengine/docs/python/ndb/queries#cursors
You can change your query to:
SocialNotification.query().order(-SocialNotification.date, SocialNotification.key).filter(SocialNotification.source_key.IN(nodes_list)).fetch_page(10)
in order to get this to work. Note that it seems to be slow (18 seconds) when nodes_list is large (1000 entities), at least on the Development server. I don't have a large amount of test
data on a test server.
You need the property you want to order on and key.
.order(-SocialNotification.date, SocialNotification.key)
I had the same error when filtering without a group.
The error occurred every time my filter returned more than one result.
To fix it I actually had to add ordering by key.

Rename field using Objectify and Google App Engine

I am trying a case where we changed a field name in our entity. we have something like this for example
class Person {
String name; //The original declaration was "String fullName"
}
According to objectify you have to use annonation #AutoLoad(""). This is ok and it works as Google Datastore doesn't delete the data Actually but it makes a new field so this annotation is like a mapping between the old and the new field. No problem when you are reading the whole table.
The problem arises when you apply a filter on your query (Suppose you made 5 objects with old name and 5 with new name). The result of your query depends on whether you used the old variable name or the new one (returns back only 5 but never the 10). It won't fetch both of them and map them. Any Suggestions for this problem? I hope i explained it in a clear way.
Thanks in advance
The simplest straight forward solution. fetch all data with the annonation "AutoLoad()". Then store them again. In this way they will be saved as the new field. The old one doesn't exist anymore or at least it doesn't contain any data anymore. It is like migrating the data from the old name to the new name. Anyone has better suggestions ?
If you've changed the name of your field, you need to load and re-put all your data (using the mapreduce API would be one option here). There's no magic way around this - the data you've stored exists with two different names on disk.
You can use #OldName
http://www.mail-archive.com/google-appengine-java#googlegroups.com/msg05586.html

Mongoid Syntax Questions

1) Finding by instance object
Assuming I have the instance object called #topic. I want to retrieve the answers for this given topic. I was thinking I should be able to pass in :topics=>#topic, but i had to do the very ugly query below.
#answers = Answers.where(:topic_ids => {"$in" => [#topic.id]})
2) Getting the string representation of the id. I have a custom function (shown below). But shouldn't this be a very common requirement?
def sid
return id.to_s
end
If your associations are set up correctly, you should be able to do:
#topic.answers
It sounds like the above is what you are looking for. Make sure you have set up your associations correctly. Mongoid is very forgiving when defining associations, so it can seem that they are set up right when there is in fact a problem like mismatched names in references_many and referenced_in.
If there's a good reason why the above doesn't work and you have to use a query, you can use this simple query:
#answers = Answer.where(:topic_ids => #topic.id)
This will match any Answer record whose topic_ids include the supplied ID. The syntax is the same for array fields as for single-value fields like Answer.where(:title => 'Foo'). MongoDB will interpret the query differently depending on whether the field is an array (check if supplied value is in the array) or a single value (check if the supplied value is a match).
Here's a little more info on how MongoDB handles array queries:
http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-ValueinanArray

Resources