QDjango: Making queries

QDjango

Making queries

The QDjango object relational mapper (ORM) supports the concept of querysets, borrowed from django's ORM. A queryset is a collection of database objects which match a certain number of user-specified conditions.

You can learn more about querysets by reading the QDjangoQuerySet template class documentation.

# Creating and filtering querysets

Before you can start using querysets, you need to declare your database models as described in Database models.

The most basic queryset matches all the objects for a given model.

// all users
QDjangoQuerySet<User> users;

You can use the QDjangoQuerySet::filter() and QDjangoQuerySet::exclude() methods to add filtering conditions to a querset:

// find all users whose password is "foo" and whose username is not "bar"
QDjangoQuerySet<User> someUsers;
someUsers = users.filter(QDjangoWhere("password", QDjangoWhere::Equals, "foo") &&
QDjangoWhere("username", QDjangoWhere::NotEquals, "bar"));
// find all users whose username is "foo" or "bar"
someUsers = users.filter(QDjangoWhere("username", QDjangoWhere::Equals, "foo") ||
QDjangoWhere("username", QDjangoWhere::Equals, "bar"));
// find all users whose username starts with "f":
someUsers = users.filter(QDjangoWhere("username", QDjangoWhere::StartsWith, "f"));

You can also use the QDjangoQuerySet::limit() method to limit the number of returned rows:

// limit number of results
someUsers = users.limit(0, 100);

# Iterating over results

The easiest way to iterate over results is to use Qt's foreach keyword:

// iterate over matching users
foreach (const User &user, someUsers) {
qDebug() << "found user" << user.username;
}

Another way of iterating over results is to run over model instances using the QDjangoQuerySet::size() and QDjangoQuerySet::at() methods:

// iterate over matching users
User user;
for (int i = 0; i < someUsers.size(); ++i) {
if (someUsers.at(i, &user)) {
qDebug() << "found user" << user.username;
}
}

It is also possible to retrieve field data without creating model instances using the QDjangoQuerySet::values() and QDjangoQuerySet::valuesList() methods:

// retrieve usernames and passwords for matching users as maps
QList<QVariantMap> propertyMaps = someUsers.values(QStringList() << "username" << "password");
foreach (const QVariantMap &propertyMap, propertyMaps) {
qDebug() << "username" << propertyList["username"];
qDebug() << "password" << propertyList["password"];
}
// retrieve usernames and passwords for matching users as lists
QList<QVariantList> propertyLists = someUsers.valuesList(QStringList() << "username" << "password");
foreach (const QVariantList &propertyList, propertyLists) {
qDebug() << "username" << propertyList[0];
qDebug() << "password" << propertyList[1];
}

# Other operations

// count matching users without retrieving their data
int numberOfUsers = someUsers.count();
// delete all the users in the queryset
someUsers.remove();

# Selecting related objects

It is efficient to fetch the main object together with the selected one. This is particularly true if multiple objects are needed so that all of them are fetched with a single query. QDjagno offers two ways how to select related objects. The default option is to traverse all foreign keys recursuvely. In case of small dependence trees this option is suitable, however when the database structure is complex, fetching all related object in a recursive manner can be overwhelming. Therefore, the QDjangoQuerySet::selectRelated() method can be invoked with a list of foreign keys that have to be traversed, thus limiting the set of fetched related objects.

Let us have the following model structure:

#include <QObject>
#include <QDjangoModel.h>
#include <QByteArray>
#include <QDateTime>
#include <enterprise.h>
#include <row_status_type.h>
#include <site_type.h>
class Author : public QDjangoModel
{ Q_OBJECT
Q_PROPERTY(long author_id READ author_id WRITE set_author_id)
Q_CLASSINFO("author_id","primary_key=true auto_increment=true")
Q_PROPERTY(QString name READ name WRITE set_name)
Q_CLASSINFO("name","max_length=254 null=true blank=true")
Q_PROPERTY(QDateTime birthday READ birthday WRITE set_birthday)
Q_CLASSINFO("birthday","null=true blank=true")
public:
Author(QObject *parent=0);
long author_id() const;
void set_author_id(long value);
QString name() const;
QDateTime birthday() const;
void set_birthday(QDateTime value);
private:
long m_author_id;
QString m_name;
QDateTime m_birthday;
};
class Location : public QDjangoModel
{ Q_OBJECT
Q_PROPERTY(long location_id READ publisher_id WRITE set_location_id)
Q_CLASSINFO("location_id","primary_key=true auto_increment=true")
Q_PROPERTY(QString name READ name WRITE set_name)
Q_CLASSINFO("name","max_length=254 null=true blank=true")
public:
Location(QObject *parent=0);
long location_id() const;
void set_location_id(long value);
QString name() const;
private:
long m_location_id;
QString m_name;
};
class Publisher : public QDjangoModel
{ Q_OBJECT
Q_PROPERTY(long publisher_id READ publisher_id WRITE set_publisher_id)
Q_CLASSINFO("author_id","primary_key=true auto_increment=true")
Q_PROPERTY(QString name READ name WRITE set_name)
Q_CLASSINFO("name","max_length=254 null=true blank=true")
Q_PROPERTY(Location* location READ location WRITE set_location)
public:
Publisher(QObject *parent=0);
long publisher_id() const;
void set_publisher_id(long value);
QString name() const;
void sel_location(Location *value);
Location* location();
private:
long m_publisher_id;
QString m_name;
};
class Book : public QDjangoModel
{ Q_OBJECT
Q_PROPERTY(long book_id READ book_id WRITE set_book_id)
Q_CLASSINFO("book_id","primary_key=true auto_increment=true")
Q_PROPERTY(QString name READ name WRITE set_name)
Q_CLASSINFO("name","max_length=254 null=true blank=true")
Q_PROPERTY(Author* author READ author WRITE set_author)
Q_PROPERTY(Publisher* publisher READ publisher WRITE set_publisher)
public:
Book(QObject *parent=0);
long book_id() const;
void set_book_id(long value);
QString name() const;
void set_author(Author* value);
Author* author();
void set_publisher(Publisher* value);
Publisher* publisher();
private:
long m_book_id;
QString m_name;
};

If one invokes QDjangoQuerySet::selectRelated() without arguments on a QuerySet of Book, QDjango will return the selected Book object with filled Author, Publisher as well as Location of the Publisher. In order to limit the pre-fetched objects, just for Author the QDjangoQuerySet::selectRelated() method should be invoked using a QStringList in the following format

QStringList relatedNames;
relatedNames << "author" << "publisher";

Limiting the pre-fetching to publisher and its location the QStringList becomes:

QStringList relatedNames;
relatedNames << "publisher__location";

Fetching all the complete structure as if the method was invoked without any argument is equivalent to the following QStringList:

QStringList relatedNames;
relatedNames << "publisher__location" << "author";

The first level of the related names represent the foreign keys of the class Book. The subsequent foreign keys of the related objects are separated by double underscore '__' as in the QDjangoWhere class.

QDjangoWhere::StartsWith
@ StartsWith
Definition: QDjangoWhere.h:52
QDjangoModel
The QDjangoModel class is the base class for all models.
Definition: QDjangoModel.h:79
QDjangoWhere
The QDjangoWhere class expresses an SQL constraint.
Definition: QDjangoWhere.h:41
QDjangoQuerySet::remove
bool remove()
Definition: QDjangoQuerySet.h:585
QDjangoWhere::Equals
@ Equals
Definition: QDjangoWhere.h:46
QDjangoQuerySet::values
QList< QVariantMap > values(const QStringList &fields=QStringList())
Definition: QDjangoQuerySet.h:638
QDjangoQuerySet::filter
QDjangoQuerySet filter(const QDjangoWhere &where) const
Definition: QDjangoQuerySet.h:496
QDjangoQuerySet::size
int size()
Definition: QDjangoQuerySet.h:616
QDjangoQuerySet
The QDjangoQuerySet class is a template class for performing database queries.
Definition: QDjangoQuerySet.h:47
QDjangoWhere::NotEquals
@ NotEquals
Definition: QDjangoWhere.h:47
QDjangoQuerySet::count
int count() const
Definition: QDjangoQuerySet.h:444
QDjangoQuerySet::valuesList
QList< QVariantList > valuesList(const QStringList &fields=QStringList())
Definition: QDjangoQuerySet.h:650
QDjangoQuerySet::at
T * at(int index, T *target=0)
Definition: QDjangoQuerySet.h:365
QDjangoQuerySet::limit
QDjangoQuerySet limit(int pos, int length=-1) const
Definition: QDjangoQuerySet.h:534