how to query a multiple column in django - python

I have a problem in displaying specific columns in my model in django...
I have read in the documentation in about the queryset feature of django.
my question is that it is also possible in django to run just like this query?
select name, age, address from person;
can anyone can give me an idea, i also try it like this
Mymodel.objects.get(name, age, address)
but there are error in the parameter of name, age and address...
thanks...

If you want only some columns use only:
Mymodel.objects.only('name', 'age', 'address')
If you don't want some columns use defer:
Mymodel.objects.defer('some_big_field')
You can still access field you haven't queried, but it will cost you one mode DB hit.
Also you can use values and values_list methods, but instead of model instances they return list of dicts and list of lists respectively.

there are a few different ways. django normally wraps the data in model instances, which is part of the point of the orm. you deal with objects and django deals with the database. so
for person in MyMydel.objects.all():
do_something_with(person.name)
having said that, if you only want certain attributes, e.g. for performance, you can use values
MyMode.objects.values('name', 'age', 'address')
which returns a list of dicts with those values

Related

How can I filter distinct values from one column in a Django queryset without PostgreSQL?

So I have a database tracking certain Wikipedia edits. Under certain, desired, circumstances, the database may save the same edit multiple times to the db, with one column having different values.
I want to be able to make a queryset that removes duplicate rows based on the rc_id column, which is the same for duplicate edits. I don't care which of the duplicate rows is discarded because I only need the non-unique information.
If I were using a PostgreSQL database I could use the DISTINCT ON feature via queryset.objects.filter(field=filter).distinct('rc_id'). In MySQL, however, this feature is not available.
Other SO questions on this topic have been answered by telling people to use .values_list('rc_id').distinct(), however I want the result to still be a queryset for further filtering, not a values list. How can I do this at the queryset level, or if necessary, with a raw SQL query?
With thanks to HÃ¥ken Lid above, my solution was the following:
ordered_queryset = queryset.order_by(
'-timestamp').values_list(
'domain', 'timestamp', 'username', 'page_title', 'edit_summary', 'rc_id', named=True
).distinct()
To clarify, each of the values in the values_list is the same for duplicate edits, and I've left out the column which is unique. As such, this returns a queryset with correctly filtered rows.

How to model a unique constraint in GAE ndb

I want to have several "bundles" (Mjbundle), which essentially are bundles of questions (Mjquestion). The Mjquestion has an integer "index" property which needs to be unique, but it should only be unique within the bundle containing it. I'm not sure how to model something like this properly, I try to do it using a structured (repeating) property below, but there is yet nothing actually constraining the uniqueness of the Mjquestion indexes. What is a better/normal/correct way of doing this?
class Mjquestion(ndb.Model):
"""This is a Mjquestion."""
index = ndb.IntegerProperty(indexed=True, required=True)
genre1 = ndb.IntegerProperty(indexed=False, required=True, choices=[1,2,3,4,5,6,7])
genre2 = ndb.IntegerProperty(indexed=False, required=True, choices=[1,2,3])
#(will add a bunch of more data properties later)
class Mjbundle(ndb.Model):
"""This is a Mjbundle."""
mjquestions = ndb.StructuredProperty(Mjquestion, repeated=True)
time = ndb.DateTimeProperty(auto_now_add=True)
(With the above model and having fetched a certain Mjbundle entity, I am not sure how to quickly fetch a Mjquestion from mjquestions based on the index. The explanation on filtering on structured properties looks like it works on the Mjbundle type level, whereas I already have a Mjbundle entity and was not sure how to quickly query only on the questions contained by that entity, without looping through them all "manually" in code.)
So I'm open to any suggestion on how to do this better.
I read this informational answer: https://stackoverflow.com/a/3855751/129202 It gives some thoughts about scalability and on a related note I will be expecting just a couple of bundles but each bundle will have questions in the thousands.
Maybe I should not use the mjquestions property of Mjbundle at all, but rather focus on parenting: each Mjquestion created should have a certain Mjbundle entity as parent. And then "manually" enforce uniqueness at "insert time" by doing an ancestor query.
When you use a StructuredProperty, all of the entities that type are stored as part of the containing entity - so when you fetch your bundle, you have already fetched all of the questions. If you stick with this way of storing things, iterating to check in code is the solution.

How can I test that Django QuerySets are ordered by PK ascending

class Foo(models.Model):
name = models.CharField(max_length=10)
class Meta(object):
ordering = ('pk', )
I want to test that this ordering is working as I expect.
def test_respect_ordering(self):
Foo.objects.create(name="bar", pk=2)
Foo.objects.create(name="baz", pk=1)
results = Foo.objects.all()
self.assertEqual("baz", results[0].name)
self.assertEqual("bar", results[1].name)
Although this works as I expect, my test passes regardless of the Meta class or the ordering property defined in it. Is there some way I can test that this code matters?
Why do I want to test this? My tests run in SQLite, but production is in mysql. Hopefully someday, we'll use a better RDMBS, and maybe results won't be returned by PK across all of these RDMBS's.
The Django docs indicate that sorting doesn't happen automatically.
If you omit the ordering attribute in your Meta class, the resulting generated SQL query will not have an ORDER BY clause (well, in 1.4 anyway). This means you can't rely on the order of the rows.
Unordered SQL queries will generally have an order that looks like it makes some sense. That's because the query plan will most likely use indexes to decrease query time, and indexes can play a big part in the row order for unordered queries. A table generated by a Django model will only have an index on the primary key unless otherwise specified, so in general the 'unordered' order will be quite similar to the order when sorted on primary key.
However, there is absolutely no guarantee here, and this order cannot be relied on. The query plan depends largely on the database engine, and it can even change drastically for very similar queries on the same engine.
If you want a particular order, you should explicitly specify the order you want. That's the only reliable way to guarantee a particular order.

How can I retrieve data from multiple tables

I need to retrieve data from multiple tables, with a dynamically built filter that might or might not use data from any of the tables.
So say I have this:
class Solution(models.Model):
name = models.CharField(max_length=MAX, unique=True)
# Other data
class ExportTrackingRecord(models.Model):
tracked_id = models.IntegerField()
solution = models.ForeignKey(Solution)
# Other data
Then elsewhere I need to do:
def get_data(user_provided_criteria):
etr = ExportTrackingRecord.objects.filter(make_Q_object(user_provided_criteria)).select_related()
for data in etr:
s = data.solution
# do things with data from both tables
As far as I can tell, if I happen to filter on a field in Solution, django will do the join, and select_related get both objects. If I only filter on fields in ExportTrackingRecord then there will be no join, and django will generate a new query for each ExportTrackingRecord in the QuerySet (which could be thousands...)
I am fairly new to django, but is there a reasonable way to force the join?
select_related() is the key to your problem. If you don't use it and don't filter on fields of the related model Django will not do a join and cause an extra query for every row in the result if you are accessing data of the related model.
If you do something like ExportTrackingRecord.objects.filter(...).select_related('solution') you force Django to always do a join with the Solution table.
If you need to do the same in the other direction, through the reverse foreign key relation ship you need prefetch_related(), same for many-to-many relations
select_related controls what gets loaded into the results when the QuerySet is evaluated. it will force the join regardless of filtering.
If you don't specify select_related, then even if your filter produces a sql query with a join, the parent model's fields won't be loaded in the results, and accessing them will still require additional queries.

Checking for group membership (Many to Many in Django)

I have two models in Django: groups and entries. Groups has a many-to-many field that connects it to entries. I want to select all entries that have a group (as not all do!) and be able to access their group.title field.
I've tried something along the lines of:
t = Entries.objects.select_related().exclude(group=None)
and while this returns all entries that have groups, I can't do t[0].groups to get the title. Any ideas on how this could be done?
Edit: more info
When ever I use Django's shell to inspect what is returned in t (in this example), t[0].group does not exist. The only way I can access this is via t[0].group_set.all()[0].title, which seems inefficient and like I'm doing something incorrectly.
You don't show the model code, so I can't be sure, but instead of t[0].groups, I think you want:
for g in t[0].groups.all():
print g.title

Categories