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.
You can use the QDjangoQuerySet::filter() and QDjangoQuerySet::exclude() methods to add filtering conditions to a querset:
You can also use the QDjangoQuerySet::limit() method to limit the number of returned rows:
someUsers = users.
limit(0, 100);
Iterating over results
The easiest way to iterate over results is to use Qt's foreach keyword:
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:
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:
QList<QVariantMap> propertyMaps = someUsers.
values(QStringList() <<
"username" <<
"password");
foreach (const QVariantMap &propertyMap, propertyMaps) {
qDebug() << "username" << propertyList["username"];
qDebug() << "password" << propertyList["password"];
}
QList<QVariantList> propertyLists = someUsers.
valuesList(QStringList() <<
"username" <<
"password");
foreach (const QVariantList &propertyList, propertyLists) {
qDebug() << "username" << propertyList[0];
qDebug() << "password" << propertyList[1];
}
Other operations
int numberOfUsers = someUsers.
count();
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>
{ 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;
};
{ 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;
};
{ 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;
};
{ 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.