virtual QNetworkReply *handleRequest(QString path, QStringList sort, Pagination *pagination, QVariantMap filters = QVariantMap(), QStringList fields = QStringList(), QString id = 0)
QNetworkReply *JsonRestListModel::fetchMoreImpl(const QModelIndex &parent) { Q_UNUSED(parent) return apiInstance()->handleRequest(requests()->get(), sort(), pagination(), filters(), fields()); }
... MyApi { id: myApi } JsonRestListModel { id: jsonSampleModel api: myApi // API idField: 'id' // - // API handleRequest // ReadOnly readOnly get ( ) getDetails ( ) // - . Requests requests { get: "/v1/coupon" getDetails: "/v1/coupon/{id}" } // filters: {'isArchive': '0'} // fields: ['id','title'] // sort: ['-id'] // pagination { policy: Pagination.PageNumber // - perPage: 20 //- } // Component.onCompleted: { reload(); } } ...
[{ "id": 1, "sourceServiceId": 2, "categoryName": "", "categoryCode": "aktsii", "categoryIdentifier": "0", "parentCategoryIdentifier": "0", "categoryAdditionalInfo": "0", "isActive": 1 }, { "id": 2, "sourceServiceId": 2, "categoryName": "", "categoryCode": "kupony", "categoryIdentifier": "28", "parentCategoryIdentifier": "28", "categoryAdditionalInfo": "https://blizzard.kz/kuponator/categ/28", "isActive": 1 } , ...]
[{ "id": 1, "sourceServiceId": 1, "cityId": 1, "createTimestamp": "2015-03-12 14:01:57", "lastUpdateDateTime": "2016-10-20 03:54:47", "recordHash": "e7b01c1a69bc66e1f1a62d8fcb0825de", "title": "Home Club", "shortDescription": " , , , ", "longDescription": " – . , – - Home Club. 50%! , , . ! ", "conditions": " <p class="e-condition__text">:</p> <ul class="b-conditions-list"> <li class="e-condition"> - Home Club.</li> <li class="e-condition"> <strong></strong>: 50% - 1 500 . 3 000 .</li> <li class="e-condition"> ( ).</li> <li class="e-condition"> .</li> <li class="e-condition"> 10 .</li> <li class="e-condition"> <strong>VIP- . VIP- .</strong> </li> <li class="e-condition"> .</li> <li class="e-condition"> <strong> :</strong><br> +7 (727) 308-23-63,<br> +7 (747) 841-42-51,<br> +7 (701) 985-90-72.</li> <li class="e-condition"> <strong> .</strong> </li> <li class="e-condition"> 2 , ( ).</li> <li class="e-condition"> , «».</li> <li class="e-condition"> Home Club : , , , Home Club.</li> <li class="e-condition"> , , .</li> <li class="e-condition"> <strong> .</strong> </li> <li class="e-condition"> 12 2015 . ().</li> <li class="e-condition"> <span hashstring="deal_refunds_policy" hashtype="content"> </span> </li> <li class="e-condition"> <span hashstring="deal_standard_conditions" hashtype="content"> </span> </li> </ul> <p class="e-offer__features"></p> <ul class="b-offer__features-list"> <li class="e-offer__feature "> , , , Home Club </li> <li class="e-offer__feature "> :<br> +7 (727) 308-23-63<br>+7 (747) 841-42-51<br>+7 (701) 985-90-72<br> </li> <li class="e-offer__feature "> :<br> : </li> </ul>", "features": " <p class="e-offer__features">:</p> <ul class="b-offer__features-list"> <li class="e-offer__feature">Home Club , , .</li> <li class="e-offer__feature"> ​ 10 (5 5 Vip-). Vip- , , -, , .</li> <li class="e-offer__feature"> ​ Home Club - 3- : <ul> <li> ;</li> <li>;</li> <li> .</li> </ul> </li> <li class="e-offer__feature"> ​ : <ul> <li> 4- 7- ;</li> <li>1 : , -, , ;</li> <li>2 : 2- , , , , ;</li> <li>3 : 2 , .</li> </ul> </li> <li class="e-offer__feature"> ​VIP-: <ul> <li> 4- 11- ;</li> <li>1 : , 10 , , , , , ;</li> <li>2 : -12 , 2- 4- ( ), 2 ..</li> </ul> </li> <li class="e-offer__feature"> : <a data-seohide-href="/deal/away/20056/" class="e-offer__feature--link seohide-link" target="_blank" rel="nofollow" title="http://www.home-club.kz/">www.home-club.kz/</a> </li> </ul>", "imagesLinks": [ "https://static.chocolife.me/static/upload/images/deal/for_deal_page/21000/20056/660x305/1_20150312023051426147565.7364.jpg", "https://static.chocolife.me/static/upload/images/deal/for_deal_page/21000/20056/660x305/2_20150312023051426147565.9348.jpg", "https://static.chocolife.me/static/upload/images/deal/for_deal_page/21000/20056/660x305/4_20150312093171426174997.7985.jpg", "https://static.chocolife.me/static/upload/images/deal/for_deal_page/21000/20056/660x305/5_20150312093171426174997.944.jpg", "https://www.chocolife.me/" ], "timeToCompletion": null, "mainImageLink": "https://www.chocolife.me/", "originalCouponPrice": "30 000", "originalPrice": "30 000", "discountPercent": "-51%", "discountPrice": "18 000", "discountType": "full", "boughtCount": "1", "sourceServiceCategories": "1 , 82 , 8 , 2", "pageLink": "https://www.chocolife.me//20056-arenda-kottedzha-s-dvumya-spalnyami-gorki-sauna-darts-i-mnogoe-drugoe-v-prirodno-razvlekatelnom-parke-home-club-skidka-do-50", "isArchive": 1, "tryToUpdateCount": 0, "viewCount": "0", "serviceName": "Chocolife.me", "cityName": "" }, { "id": 2, "sourceServiceId": 1, "cityId": 1, "createTimestamp": "2015-03-12 14:01:57", "lastUpdateDateTime": "2016-11-01 12:39:53", "recordHash": "dce10232f1acb53b1ee7a8bf3902e0c0", "title": " AquaBike Centre", "shortDescription": " ", "longDescription": null, "conditions": null, "features": " <p class="e-offer__features">:</p> <ul class="b-offer__features-list"> <li class="e-offer__feature"> . .</li> <li class="e-offer__feature"> Aquabike – : <ul> <li> ;</li> <li> ;</li> <li> ;</li> <li> ;</li> <li> ;</li> <li> ;</li> <li> ;</li> <li> .</li> </ul> </li> <li class="e-offer__feature"> <strong> :</strong> <ul> <li> ;</li> <li> ;</li> <li> , ;</li> <li> ;</li> <li> , ;</li> <li> , ;</li> <li> ;</li> <li> , , .</li> </ul> </li> <li class="e-offer__feature"> <strong> 1 .</strong> </li> <li class="e-offer__feature"> AquaBike Centre : <ul> <li> , 2 ;</li> <li> ;</li> <li>, 45 .</li> </ul> </li> </ul>", "imagesLinks": [ "https://static.chocolife.me/static/upload/images/deal/for_deal_page/21000/20016/660x305/1_20150314013241426318344.7033.jpg", "https://static.chocolife.me/static/upload/images/deal/for_deal_page/21000/20016/660x305/2_20150314013241426318344.8157.JPG", "https://static.chocolife.me/static/upload/images/deal/for_deal_page/21000/20016/660x305/4_20150311053411426073981.6524.JPG", "https://www.chocolife.me/" ], "timeToCompletion": null, "mainImageLink": "https://www.chocolife.me/", "originalCouponPrice": "3 000", "originalPrice": "3 000", "discountPercent": "-50%", "discountPrice": "1 500", "discountType": "full", "boughtCount": "58", "sourceServiceCategories": "1 , 68 , 36 , 2", "pageLink": "https://www.chocolife.me//20016-novinka-iz-francii-vse-dlya-vashey-krasoty-zdorovya-i-relaksacii-trenirovki-po-akvabaykingu-a-takzhe-pressoterapiya-so-skidkoy-50-v-aquabike-centre", "isArchive": 1, "tryToUpdateCount": 0, "viewCount": "0", "serviceName": "Chocolife.me", "cityName": "" }, ...]
{ "id": 1, "sourceServiceId": 1, "cityId": 1, "createTimestamp": "2015-03-12 14:01:57", "lastUpdateDateTime": "2016-10-20 03:54:47", "recordHash": "e7b01c1a69bc66e1f1a62d8fcb0825de", "title": "Home Club", "shortDescription": " , , , ", "longDescription": " – . , – - Home Club. 50%! , , . ! ", "conditions": " <p class="e-condition__text">:</p> <ul class="b-conditions-list"> <li class="e-condition"> - Home Club.</li> <li class="e-condition"> <strong></strong>: 50% - 1 500 . 3 000 .</li> <li class="e-condition"> ( ).</li> <li class="e-condition"> .</li> <li class="e-condition"> 10 .</li> <li class="e-condition"> <strong>VIP- . VIP- .</strong> </li> <li class="e-condition"> .</li> <li class="e-condition"> <strong> :</strong><br> +7 (727) 308-23-63,<br> +7 (747) 841-42-51,<br> +7 (701) 985-90-72.</li> <li class="e-condition"> <strong> .</strong> </li> <li class="e-condition"> 2 , ( ).</li> <li class="e-condition"> , «».</li> <li class="e-condition"> Home Club : , , , Home Club.</li> <li class="e-condition"> , , .</li> <li class="e-condition"> <strong> .</strong> </li> <li class="e-condition"> 12 2015 . ().</li> <li class="e-condition"> <span hashstring="deal_refunds_policy" hashtype="content"> </span> </li> <li class="e-condition"> <span hashstring="deal_standard_conditions" hashtype="content"> </span> </li> </ul> <p class="e-offer__features"></p> <ul class="b-offer__features-list"> <li class="e-offer__feature "> , , , Home Club </li> <li class="e-offer__feature "> :<br> +7 (727) 308-23-63<br>+7 (747) 841-42-51<br>+7 (701) 985-90-72<br> </li> <li class="e-offer__feature "> :<br> : </li> </ul>", "features": " <p class="e-offer__features">:</p> <ul class="b-offer__features-list"> <li class="e-offer__feature">Home Club , , .</li> <li class="e-offer__feature"> ​ 10 (5 5 Vip-). Vip- , , -, , .</li> <li class="e-offer__feature"> ​ Home Club - 3- : <ul> <li> ;</li> <li>;</li> <li> .</li> </ul> </li> <li class="e-offer__feature"> ​ : <ul> <li> 4- 7- ;</li> <li>1 : , -, , ;</li> <li>2 : 2- , , , , ;</li> <li>3 : 2 , .</li> </ul> </li> <li class="e-offer__feature"> ​VIP-: <ul> <li> 4- 11- ;</li> <li>1 : , 10 , , , , , ;</li> <li>2 : -12 , 2- 4- ( ), 2 ..</li> </ul> </li> <li class="e-offer__feature"> : <a data-seohide-href="/deal/away/20056/" class="e-offer__feature--link seohide-link" target="_blank" rel="nofollow" title="http://www.home-club.kz/">www.home-club.kz/</a> </li> </ul>", "imagesLinks": [ "https://static.chocolife.me/static/upload/images/deal/for_deal_page/21000/20056/660x305/1_20150312023051426147565.7364.jpg", "https://static.chocolife.me/static/upload/images/deal/for_deal_page/21000/20056/660x305/2_20150312023051426147565.9348.jpg", "https://static.chocolife.me/static/upload/images/deal/for_deal_page/21000/20056/660x305/4_20150312093171426174997.7985.jpg", "https://static.chocolife.me/static/upload/images/deal/for_deal_page/21000/20056/660x305/5_20150312093171426174997.944.jpg", "https://www.chocolife.me/" ], "timeToCompletion": null, "mainImageLink": "https://www.chocolife.me/", "originalCouponPrice": "30 000", "originalPrice": "30 000", "discountPercent": "-51%", "discountPrice": "18 000", "discountType": "full", "boughtCount": "1", "sourceServiceCategories": "1 , 82 , 8 , 2", "pageLink": "https://www.chocolife.me//20056-arenda-kottedzha-s-dvumya-spalnyami-gorki-sauna-darts-i-mnogoe-drugoe-v-prirodno-razvlekatelnom-parke-home-club-skidka-do-50", "isArchive": 1, "tryToUpdateCount": 0, "viewCount": "0", "serviceName": "Chocolife.me", "cityName": "" }
#ifndef SKIDKZAPI_H #define SKIDKZAPI_H #include "apibase.h" #include <QtQml> class SkidKZApi : public APIBase { Q_OBJECT public: Q_INVOKABLE explicit SkidKZApi(); // . QML static void declareQML() { qmlRegisterType<SkidKZApi>("com.github.qtrestexample.skidkzapi", 1, 0, "SkidKZApi"); } // ReadOnly QNetworkReply *handleRequest(QString path, QStringList sort, Pagination *pagination, QVariantMap filters = QVariantMap(), QStringList fields = QStringList(), QString id = 0); // /v1/coupon QNetworkReply *getCoupons(QStringList sort, Pagination *pagination, QVariantMap filters = QVariantMap(), QStringList fields = QStringList()); // /v1/coupon/{id} QNetworkReply *getCouponDetail(QString id); // /v1/categories QNetworkReply *getCategories(QStringList sort, Pagination *pagination); }; #endif // SKIDKZAPI_H
#include "skidkzapi.h" #include <QFile> #include <QTextStream> #include <QUrlQuery> SkidKZApi::SkidKZApi() : APIBase(0) { } QNetworkReply *SkidKZApi::handleRequest(QString path, QStringList sort, Pagination *pagination, QVariantMap filters, QStringList fields, QString id) { // , if (path == "/v1/coupon") { return getCoupons(sort, pagination, filters, fields); } else if (path == "/v1/coupon/{id}") { return getCouponDetail(id); } else if (path == "/v1/categories") { return getCategories(sort, pagination); } } // , , QNetworkReply *SkidKZApi::getCoupons(QStringList sort, Pagination *pagination, QVariantMap filters, QStringList fields) { // QUrl url = QUrl(baseUrl()+"/v1/coupon"); QUrlQuery query; // if (!sort.isEmpty()) { query.addQueryItem("sort", sort.join(",")); } // switch(pagination->policy()) { case Pagination::PageNumber: query.addQueryItem("per-page", QString::number(pagination->perPage())); query.addQueryItem("page", QString::number(pagination->currentPage())); break; case Pagination::None: case Pagination::Infinity: case Pagination::LimitOffset: case Pagination::Cursor: default: break; } // . , - if (!filters.isEmpty()) { QMapIterator<QString, QVariant> i(filters); while (i.hasNext()) { i.next(); query.addQueryItem(i.key(), i.value().toString()); } } // if (!fields.isEmpty()) { query.addQueryItem("fields", fields.join(",")); } // url.setQuery(query.query()); // GET QNetworkReply *reply = get(url); return reply; } // QNetworkReply *SkidKZApi::getCouponDetail(QString id) { if (id.isEmpty()) { qDebug() << "ID is empty!"; return 0; } // GET QUrl url = QUrl(baseUrl()+"/v1/coupon/"+id); QNetworkReply *reply = get(url); return reply; } // , QNetworkReply *SkidKZApi::getCategories(QStringList sort, Pagination *pagination) { // QUrl url = QUrl(baseUrl()+"/v1/categories"); QUrlQuery query; // if (!sort.isEmpty()) { query.addQueryItem("sort", sort.join(",")); } // switch(pagination->policy()) { case Pagination::PageNumber: query.addQueryItem("per-page", QString::number(pagination->perPage())); query.addQueryItem("page", QString::number(pagination->currentPage())); break; case Pagination::None: case Pagination::Infinity: case Pagination::LimitOffset: case Pagination::Cursor: default: break; } url.setQuery(query.query()); QNetworkReply *reply = get(url); return reply; }
#ifndef COUPONMODEL_H #define COUPONMODEL_H #include "abstractjsonrestlistmodel.h" #include "api/skidkzapi.h" class CouponModel : public AbstractJsonRestListModel { Q_OBJECT public: explicit CouponModel(QObject *parent = 0); // QML ( main.cpp QML) static void declareQML() { AbstractJsonRestListModel::declareQML(); qmlRegisterType<CouponModel>("com.github.qtrestexample.coupons", 1, 0, "CouponModel"); } protected: // API QNetworkReply *fetchMoreImpl(const QModelIndex &parent); QNetworkReply *fetchDetailImpl(QString id); // QVariantMap preProcessItem(QVariantMap item); }; #endif // COUPONMODEL_H
#include "couponmodel.h" CouponModel::CouponModel(QObject *parent) : AbstractJsonRestListModel(parent) { } QNetworkReply *CouponModel::fetchMoreImpl(const QModelIndex &parent) { Q_UNUSED(parent) // API return static_cast<SkidKZApi *>(apiInstance())->getCoupons(sort(), pagination(), filters(), fields()); } QNetworkReply *CouponModel::fetchDetailImpl(QString id) { // API return static_cast<SkidKZApi *>(apiInstance())->getCouponDetail(id); } QVariantMap CouponModel::preProcessItem(QVariantMap item) { // createTimestamp QDate date = QDateTime::fromString(item.value("createTimestamp").toString(), "yyyy-MM-dd hh:mm:ss").date(); item.insert("createDate", date.toString("dd.MM.yyyy")); // - originalCouponPrice QString originalCouponPrice = item.value("originalCouponPrice").toString().trimmed(); if (originalCouponPrice.isEmpty()) { originalCouponPrice = "?"; } QString discountPercent = item.value("discountPercent").toString().trimmed().remove("—").remove("-").remove("%"); if (discountPercent.isEmpty()) { discountPercent = "?"; } QString originalPrice = item.value("originalPrice").toString().trimmed(); if (originalPrice.isEmpty()) { originalPrice = "?"; } QString discountPrice = item.value("discountPrice").toString().remove(".").trimmed(); if (discountPrice.isEmpty()) { discountPrice = "?"; } // discountString, API QString discountType = item.value("discountType").toString(); QString discountString = tr("Undefined Type"); if (discountType == "freeCoupon" || discountType == "coupon") { discountString = tr("Coupon: %1. Discount: %2%").arg(originalCouponPrice).arg(discountPercent); } else if (discountType == "full") { discountString = tr("Cost: %1. Certificate: %2. Discount: %3%").arg(originalPrice).arg(discountPrice).arg(discountPercent); } item.insert("discountString", discountString); return item; }
... import com.github.qtrestexample.skidkzapi 1.0 import com.github.qtrest.jsonrestlistmodel 1.0 import com.github.qtrest.pagination 1.0 import com.github.qtrest.requests 1.0 ... //API , , - =) SkidKZApi { id: skidKZApi baseUrl: "http://api.skid.kz" authTokenHeader: "Authorization" authToken: "Bearer 8aef452ee3b32466209535b96d456b06" Component.onCompleted: console.log("completed!"); } // , ReadOnly // , - , JsonRestListModel { id: categoriesRestModel api: skidKZApi idField: 'id' requests { get: "/v1/categories" } sort: ['categoryName'] pagination { policy: Pagination.PageNumber perPage: 20 currentPageHeader: "X-Pagination-Current-Page" totalCountHeader: "X-Pagination-Total-Count" pageCountHeader: "X-Pagination-Page-Count" } Component.onCompleted: { console.log(pagination.perPage); reload(); } } // CouponModel , requests, .. fetchMoreImpl. CouponModel { id: coupons; api: skidKZApi filters: {'isArchive': '0'} idField: 'id' fields: ['id','title','sourceServiceId','imagesLinks', 'mainImageLink','pageLink','cityId','boughtCount', 'shortDescription','createTimestamp', 'serviceName', 'discountType', 'originalCouponPrice', 'originalPrice', 'discountPercent', 'discountPrice'] sort: ['-id'] pagination { policy: Pagination.PageNumber perPage: 20 currentPageHeader: "X-Pagination-Current-Page" totalCountHeader: "X-Pagination-Total-Count" pageCountHeader: "X-Pagination-Page-Count" } Component.onCompleted: { console.log(pagination.perPage); reload(); } }
Source: https://habr.com/ru/post/314984/
All Articles