Is it possible to retrieve the subset of fields using Django mongodb nonrel. I am totally new to python, but have good knowledge in mongo.
My requirement is very straight forward, I wanted to query the collection by its embedded field and return only some specific fields
I could do that in mongodb by
db.Contract.find({'owner.name':'Ram'},{'address':1})
and I tried this in django
Contract.objects.filter(owner__name='Ram')
but it throws an error
raise FieldError("Join on field %r not permitted. Did you misspell %r
for the lookup type?" % (name, names[pos + 1])) FieldError: Join on
field 'owner' not permitted. Did you misspell 'name' for the
lookup type?
am totally struck here. I believe i have my models as specified in the documentation.
class SimplePerson(models.Model):
name = models.CharField(max_length=255)
user_key = models.CharField(max_length=255)
class Contract(models.Model):
owner = EmbeddedModelField('SimplePerson')
title = models.CharField(max_length=120, )
This is really weird. I could't find any reference in the documentation site about how to query the embedded field & retrieve the subset of fields.
Finally I used raw_query to query the embedded field
Contract.objects.raw_query({'owner.name':'Ram'})
But still not able to figure out how to retrieve the subset of fields. Can someone help me out?
Subobject filters aren't possible yet so you need to drop down to raw_query (which you already figured out). To retrive a subset of fields, use .values('field1', 'field2', ...).
Filtering by EmbeddedField is now possible with the following syntax:
Contract.objects.filter(owner={'name': 'Ram'})
Related
I have a table called user_info. I want to get names of all the users. So the table has a field called name. So in sql I do something like
SELECT distinct(name) from user_info
But I am not able to figure out how to do the same in django. Usually if I already have certain value known, then I can do something like below.
user_info.objects.filter(name='Alex')
And then get the information for that particular user.
But in this case for the given table, I want to get all the name values using django ORM just like I do in sql.
Here is my django model
class user_info(models.Model):
name = models.CharField(max_length=255)
priority = models.CharField(max_length=1)
org = models.CharField(max_length=20)
How can I do this in django?
You can use values_list.
user_info.objects.values_list('name', flat=True).distinct()
Note, in Python classes are usually defined in InitialCaps: your model should be UserInfo.
You can use values_list() as given in Daniel's answer, which will provide you your data in a list containing the values in the field. Or you can also use, values() like this:
user_info.object.values('name')
which will return you a queryset containing a dictionary. values_list() and values() are used to select the columns in a table.
Adding on to the accepted answer, if the field is a foreign key the id values(numerical) are returned in the queryset. Hence if you are expecting other kinds of values defined in the model of which the foreign key is part then you have to modify the query like this:
`Post.objects.values_list('author__username')`
Post is a model class having author as a foreign key field which in turn has its username field:
Here, "author" field was appended with double undersocre followed by the field "name", otherwise primary key of the model will be returned in queryset. I assume this was #Carlo's doubt in accepted answer.
Let's say we have a two models like these:
Artist(models.Model):
name = models.CharField(max_length=50)
Track(models.Model):
title = models.CharField(max_length=50)
artist = models.ForeignKey(Artist, related_name='tracks')
How can I filter this relationship to get the first foreign record?
So I've tried something like this, but it didn't work (as expected)
artists = Artist.objects.filter(tracks__first__title=<some-title>)
artists = Artist.objects.filter(tracks[0]__title=<some-title>)
Is there any way to make this work?
Here's a solution not taking performance into consideration.
Artist.objects.filter(tracks__in=[a.tracks.first() for a in Artist.objects.all()], tracks__title=<some_title>)
No list approach, as requested.
Artist.objects.filter(tracks__in=Track.objects.all().distinct('artist').order_by('artist', 'id'), tracks__title=<some_title>)
The order_by 'id' is important to make sure distinct gets the first track based on insertion. The order_by 'artist' is a requirement for sorting distinct queries. Read about it here: https://www.postgresql.org/docs/9.0/static/sql-select.html#SQL-DISTINCT
I have a model with a field that is a list.
For example:
mymodel.sessions = [session1, session2]
I need a query to get all mymodels that session1 is exist their sessions.
The model`s field looks like that
sessions = models.ForeignKey("Session", related_name="abstracts",
null=True, blank=True)
Thank you !
You can use reverse lookups that go back along the foreign key to query for values in the related model.
MyModel.objects.filter(sessions__id=1)
That will filter all MyModels that have a foreign key to a session with an id of 1.
For more information see https://docs.djangoproject.com/en/1.10/topics/db/queries/#lookups-that-span-relationships
From the Django docs for filter:
filter(**kwargs)
Returns a new QuerySet containing objects that match the given lookup parameters.
You can filter on a ForeignKey relationship using the id, if you have it:
The field specified in a lookup has to be the name of a model field. There’s one exception though, in case of a ForeignKey you can specify the field name suffixed with _id. In this case, the value parameter is expected to contain the raw value of the foreign model’s primary key.
In your instance, this would like the following:
mymodel.objects.filter(sessions_id=4)
If you want to filter on any other field in the Sessions model, simply use a double underscore with the field. Some examples:
mymodel.objects.filter(sessions__name='session1')
mymodel.objects.filter(sessions__name__contains='1')
I'm using Django (I'm new to it). I want to define a foreign key, and I'm not sure how to go about it.
I have a table called stat_types:
class StatTypes(models.Model):
stat_type = models.CharField(max_length=20)
Now I want to define a foreign key in the overall_stats table to the stat_type id that is automatically generated by django. Would that be the following?
stat_types_id = models.ForeignKey('beta.StatTypes')
What if I wanted instead to have the stat_type column of the stat_types table be the foreign key. Would that be:
stat_type = models.ForeignKey('beta.StatTypes')
I guess my confusion arises in not knowing what to name the column in the second model, in order for it to know which column of the first model to use as the foreign key.
Thanks!
it does not matter what name you give to FK column name. Django figures it out that it is a ForeignKey and appends _id to the field. So you do not need _id here. I think this is good enough
stat_type = models.ForeignKey('beta.StatTypes')
Doc says:
It’s suggested, but not required, that the name of a ForeignKey field
(manufacturer in the example above) be the name of the model,
lowercase. You can, of course, call the field whatever you want.
I have a user model set up like this.
class ExternalUserModel(models.Model):
email = models.EmailField()
# other fields
class MyUserModel(models.Model):
external_user = models.ForeignKey(ExternalUserModel)
# other fields
And I am trying to get a list of MyUserModel from a list of emails.
This is the query I'm tying to perform:
MyUserModel.objects.filter(external_user__email__iexact__in=user_emails)
But I'm getting this error:
Unsupported lookup 'iexact' for EmailField or join on the field not permitted.
I need iexact since the list of emails are based on user input and may not match the casing stored in the data base.
How should I go about making this query?
The Django ORM doesn't directly support that. I don't think the database back ends do either. You can get the results you're looking for by combining multiple __iexact filters as shown in the various answers here: How to dynamically compose an OR query filter in Django?
Of the options shown there, I prefer the reduce(operator.or_, ...) syntax over for loops, but that's personal preference.
An email must be complete, so, it should be exact, you don't need to use the __iexact lookup. You just need:
MyUserModel.objects.filter(external_user__email__in=user_emails)