diff --git a/pgd_core/fixtures/users.json b/pgd_core/fixtures/users.json
new file mode 100644
index 0000000..da2eb17
--- /dev/null
+++ b/pgd_core/fixtures/users.json
@@ -0,0 +1,140 @@
+[
+{
+ "pk": 1,
+ "model": "auth.user",
+ "fields": {
+ "username": "root",
+ "first_name": "",
+ "last_name": "",
+ "is_active": true,
+ "is_superuser": true,
+ "is_staff": true,
+ "last_login": "2015-07-09T10:52:08Z",
+ "groups": [],
+ "user_permissions": [],
+ "password": "pbkdf2_sha256$12000$DJ5L0kzPsTr1$Gimu9KwMU8WB9ndI+xS8XeVeDgOpLUKlNy/4o2nhlVQ=",
+ "email": "pgd-root@example.org",
+ "date_joined": "2015-07-09T10:38:53Z"
+ }
+},
+{
+ "pk": 2,
+ "model": "auth.user",
+ "fields": {
+ "username": "test_user",
+ "first_name": "Ping",
+ "last_name": "Pong",
+ "is_active": true,
+ "is_superuser": false,
+ "is_staff": false,
+ "last_login": "2015-07-09T11:58:55Z",
+ "groups": [],
+ "user_permissions": [],
+ "password": "pbkdf2_sha256$12000$xa7FI4qkDA0n$MH3kvXCFH62Uvl2HhFT1dqehYjMV2TeqodMZHRVRZEU=",
+ "email": "example@example.org",
+ "date_joined": "2015-07-09T10:52:44Z"
+ }
+},
+{
+ "pk": 3,
+ "model": "auth.user",
+ "fields": {
+ "username": "test",
+ "first_name": "Frank",
+ "last_name": "Underwood",
+ "is_active": true,
+ "is_superuser": false,
+ "is_staff": false,
+ "last_login": "2015-07-09T11:12:12Z",
+ "groups": [],
+ "user_permissions": [],
+ "password": "pbkdf2_sha256$12000$UzZLeGQF46ef$C6Wo+2/G64z6+q09OBBs4qjlqGa8mzvAquwSuhGUayc=",
+ "email": "a@example.org",
+ "date_joined": "2015-07-09T10:55:06Z"
+ }
+},
+{
+ "pk": 1,
+ "model": "pgd_search.search",
+ "fields": {
+ "dataset_version": "",
+ "description": "Hey there, this is a test search that's being saved",
+ "title": "Test save",
+ "timestamp": "2015-07-09T11:54:21Z",
+ "isPublic": true,
+ "user": 3,
+ "data_internal": "(dp1\nS'ss_1'\np2\n(lp3\nsS'bg_i_4'\np4\nI1\nsS'bg_i_5'\np5\nI1\nsS'bg_i_2'\np6\nI1\nsS'bg_i_3'\np7\nI1\nsS'bg_i_0'\np8\nI1\nsS'resolutionMin'\np9\nF0\nsS'threshold'\np10\nV25\np11\nsS'bg_-2'\np12\nV<25\np13\nsS'bg_-3'\np14\nV<25\np15\nsS'rfreeMax'\np16\nF0.29999999999999999\nsS'ome_i_3'\np17\nI1\nsS'ome_i_2'\np18\nI1\nsS'ome_i_1'\np19\nI1\nsS'ome_i_0'\np20\nI1\nsS'ome_i_5'\np21\nI1\nsS'ome_i_4'\np22\nI1\nsS'bg_i_1'\np23\nI1\nsS'aa_i_1'\np24\nI1\nsS'aa_i_0'\np25\nI1\nsS'aa_i_-1'\np26\nI1\nsS'bm_i_-2'\np27\nI1\nsS'bm_i_-3'\np28\nI1\nsS'bm_i_-1'\np29\nI1\nsS'bm_i_-4'\np30\nI1\nsS'bs_i_2'\np31\nI1\nsS'bs_i_3'\np32\nI1\nsS'bs_i_0'\np33\nI1\nsS'bs_i_1'\np34\nI1\nsS'aa_3'\np35\n(lp36\nsS'aa_2'\np37\n(lp38\nsS'bs_i_4'\np39\nI1\nsS'bs_i_5'\np40\nI1\nsS'aa_-4'\np41\n(lp42\nsS'aa_-3'\np43\n(lp44\nsS'aa_-2'\np45\n(lp46\nsS'aa_-1'\np47\n(lp48\nVa\nasS'rfactorMin'\np49\nF0\nsS'bm_i_4'\np50\nI1\nsS'bm_i_5'\np51\nI1\nsS'bm_i_0'\np52\nI1\nsS'bm_i_1'\np53\nI1\nsS'bm_i_2'\np54\nI1\nsS'bm_i_3'\np55\nI1\nsS'rfactorMax'\np56\nF0.25\nsS'bm_0'\np57\nV<25\np58\nsS'aa_5'\np59\n(lp60\nsS'aa_4'\np61\n(lp62\nsS'resolutionMax'\np63\nF1.2\nsS'aa_1'\np64\n(lp65\nVn\nasS'aa_0'\np66\n(lp67\nVr\nasS'ome_i_-3'\np68\nI1\nsS'ome_i_-2'\np69\nI1\nsS'ome_i_-1'\np70\nI1\nsS'ome_i_-4'\np71\nI1\nsS'ss_0'\np72\n(lp73\nsS'ome_5'\np74\nV<=-90,>=90\np75\nsS'ome_4'\np76\nV<=-90,>=90\np77\nsS'ome_1'\np78\nV<=-90,>=90\np79\nsS'ome_0'\np80\nV<=-90,>=90\np81\nsS'ome_3'\np82\nV<=-90,>=90\np83\nsS'ome_2'\np84\nV<=-90,>=90\np85\nsS'bg_i_-1'\np86\nI1\nsS'bg_i_-2'\np87\nI1\nsS'bg_i_-3'\np88\nI1\nsS'bg_i_-4'\np89\nI1\nsS'bs_i_-4'\np90\nI1\nsS'ss_5'\np91\n(lp92\nsS'ss_4'\np93\n(lp94\nsS'ss_3'\np95\n(lp96\nsS'bs_i_-1'\np97\nI1\nsS'bs_i_-2'\np98\nI1\nsS'bs_i_-3'\np99\nI1\nsS'bg_-4'\np100\nV<25\np101\nsS'ss_-4'\np102\n(lp103\nsS'ss_-3'\np104\n(lp105\nsS'ss_-2'\np106\n(lp107\nsS'ss_-1'\np108\n(lp109\nsS'bg_-1'\np110\nV<25\np111\nsS'ome_-1'\np112\nV<=-90,>=90\np113\nsS'ome_-3'\np114\nV<=-90,>=90\np115\nsS'ome_-2'\np116\nV<=-90,>=90\np117\nsS'ome_-4'\np118\nV<=-90,>=90\np119\nsS'rfreeMin'\np120\nF0\nsS'bm_-1'\np121\nV<25\np122\nsS'bm_-2'\np123\nV<25\np124\nsS'bm_-3'\np125\nV<25\np126\nsS'bm_-4'\np127\nV<25\np128\nsS'bs_4'\np129\nV<25\np130\nsS'bs_5'\np131\nV<25\np132\nsS'bs_0'\np133\nV<25\np134\nsS'bs_1'\np135\nV<25\np136\nsS'bs_2'\np137\nV<25\np138\nsS'bs_3'\np139\nV<25\np140\nsS'bg_0'\np141\nV<25\np142\nsS'bg_1'\np143\nV<25\np144\nsS'bg_2'\np145\nV<25\np146\nsS'bg_3'\np147\nV<25\np148\nsS'bg_4'\np149\nV<25\np150\nsS'bg_5'\np151\nV<25\np152\nsS'bm_4'\np153\nV<25\np154\nsS'bm_5'\np155\nV<25\np156\nsS'bm_2'\np157\nV<25\np158\nsS'bm_3'\np159\nV<25\np160\nsS'residues'\np161\nV3\nsS'bm_1'\np162\nV<25\np163\nsS'bs_-2'\np164\nV<25\np165\nsS'bs_-3'\np166\nV<25\np167\nsS'bs_-1'\np168\nV<25\np169\nsS'bs_-4'\np170\nV<25\np171\nsS'ss_2'\np172\n(lp173\ns.",
+ "tags": "Ala, Arg, Asn"
+ }
+},
+{
+ "pk": 2,
+ "model": "pgd_search.search",
+ "fields": {
+ "dataset_version": "",
+ "description": "Hey there, this is again a test search",
+ "title": "Test Save 2",
+ "timestamp": "2015-07-09T11:55:38Z",
+ "isPublic": true,
+ "user": 3,
+ "data_internal": "(dp1\nS'ss_1'\np2\n(lp3\nsS'bg_i_4'\np4\nI1\nsS'bg_i_5'\np5\nI1\nsS'bg_i_2'\np6\nI1\nsS'bg_i_3'\np7\nI1\nsS'bg_i_0'\np8\nI1\nsS'resolutionMin'\np9\nF0\nsS'threshold'\np10\nV25\np11\nsS'bg_-2'\np12\nV<25\np13\nsS'bg_-3'\np14\nV<25\np15\nsS'rfreeMax'\np16\nF0.29999999999999999\nsS'ome_i_3'\np17\nI1\nsS'ome_i_2'\np18\nI1\nsS'ome_i_1'\np19\nI1\nsS'ome_i_0'\np20\nI1\nsS'ome_i_5'\np21\nI1\nsS'ome_i_4'\np22\nI1\nsS'bg_i_1'\np23\nI1\nsS'aa_i_1'\np24\nI1\nsS'aa_i_0'\np25\nI1\nsS'aa_i_-1'\np26\nI1\nsS'bm_i_-2'\np27\nI1\nsS'bm_i_-3'\np28\nI1\nsS'bm_i_-1'\np29\nI1\nsS'bm_i_-4'\np30\nI1\nsS'bs_i_2'\np31\nI1\nsS'bs_i_3'\np32\nI1\nsS'bs_i_0'\np33\nI1\nsS'bs_i_1'\np34\nI1\nsS'aa_3'\np35\n(lp36\nsS'aa_2'\np37\n(lp38\nsS'bs_i_4'\np39\nI1\nsS'bs_i_5'\np40\nI1\nsS'aa_-4'\np41\n(lp42\nsS'aa_-3'\np43\n(lp44\nsS'aa_-2'\np45\n(lp46\nsS'aa_-1'\np47\n(lp48\nVn\nasS'rfactorMin'\np49\nF0\nsS'bm_i_4'\np50\nI1\nsS'bm_i_5'\np51\nI1\nsS'bm_i_0'\np52\nI1\nsS'bm_i_1'\np53\nI1\nsS'bm_i_2'\np54\nI1\nsS'bm_i_3'\np55\nI1\nsS'rfactorMax'\np56\nF0.25\nsS'bm_0'\np57\nV<25\np58\nsS'aa_5'\np59\n(lp60\nsS'aa_4'\np61\n(lp62\nsS'resolutionMax'\np63\nF1.2\nsS'aa_1'\np64\n(lp65\nVc\nasS'aa_0'\np66\n(lp67\nVd\nasS'ome_i_-3'\np68\nI1\nsS'ome_i_-2'\np69\nI1\nsS'ome_i_-1'\np70\nI1\nsS'ome_i_-4'\np71\nI1\nsS'ss_0'\np72\n(lp73\nsS'ome_5'\np74\nV<=-90,>=90\np75\nsS'ome_4'\np76\nV<=-90,>=90\np77\nsS'ome_1'\np78\nV<=-90,>=90\np79\nsS'ome_0'\np80\nV<=-90,>=90\np81\nsS'ome_3'\np82\nV<=-90,>=90\np83\nsS'ome_2'\np84\nV<=-90,>=90\np85\nsS'bg_i_-1'\np86\nI1\nsS'bg_i_-2'\np87\nI1\nsS'bg_i_-3'\np88\nI1\nsS'bg_i_-4'\np89\nI1\nsS'bs_i_-4'\np90\nI1\nsS'ss_5'\np91\n(lp92\nsS'ss_4'\np93\n(lp94\nsS'ss_3'\np95\n(lp96\nsS'bs_i_-1'\np97\nI1\nsS'bs_i_-2'\np98\nI1\nsS'bs_i_-3'\np99\nI1\nsS'bg_-4'\np100\nV<25\np101\nsS'ss_-4'\np102\n(lp103\nsS'ss_-3'\np104\n(lp105\nsS'ss_-2'\np106\n(lp107\nsS'ss_-1'\np108\n(lp109\nsS'bg_-1'\np110\nV<25\np111\nsS'ome_-1'\np112\nV<=-90,>=90\np113\nsS'ome_-3'\np114\nV<=-90,>=90\np115\nsS'ome_-2'\np116\nV<=-90,>=90\np117\nsS'ome_-4'\np118\nV<=-90,>=90\np119\nsS'rfreeMin'\np120\nF0\nsS'bm_-1'\np121\nV<25\np122\nsS'bm_-2'\np123\nV<25\np124\nsS'bm_-3'\np125\nV<25\np126\nsS'bm_-4'\np127\nV<25\np128\nsS'bs_4'\np129\nV<25\np130\nsS'bs_5'\np131\nV<25\np132\nsS'bs_0'\np133\nV<25\np134\nsS'bs_1'\np135\nV<25\np136\nsS'bs_2'\np137\nV<25\np138\nsS'bs_3'\np139\nV<25\np140\nsS'bg_0'\np141\nV<25\np142\nsS'bg_1'\np143\nV<25\np144\nsS'bg_2'\np145\nV<25\np146\nsS'bg_3'\np147\nV<25\np148\nsS'bg_4'\np149\nV<25\np150\nsS'bg_5'\np151\nV<25\np152\nsS'bm_4'\np153\nV<25\np154\nsS'bm_5'\np155\nV<25\np156\nsS'bm_2'\np157\nV<25\np158\nsS'bm_3'\np159\nV<25\np160\nsS'residues'\np161\nV3\nsS'bm_1'\np162\nV<25\np163\nsS'bs_-2'\np164\nV<25\np165\nsS'bs_-3'\np166\nV<25\np167\nsS'bs_-1'\np168\nV<25\np169\nsS'bs_-4'\np170\nV<25\np171\nsS'ss_2'\np172\n(lp173\ns.",
+ "tags": "Asn, Asp, Cys"
+ }
+},
+{
+ "pk": 3,
+ "model": "pgd_search.search",
+ "fields": {
+ "dataset_version": "",
+ "description": "Hey there, this is again a test search",
+ "title": "Test Save 3",
+ "timestamp": "2015-07-09T11:57:07Z",
+ "isPublic": false,
+ "user": 3,
+ "data_internal": "(dp1\nS'ss_1'\np2\n(lp3\nsS'bg_i_4'\np4\nI1\nsS'bg_i_5'\np5\nI1\nsS'bg_i_2'\np6\nI1\nsS'bg_i_3'\np7\nI1\nsS'bg_i_0'\np8\nI1\nsS'resolutionMin'\np9\nF0\nsS'threshold'\np10\nV25\np11\nsS'bg_-2'\np12\nV<25\np13\nsS'bg_-3'\np14\nV<25\np15\nsS'rfreeMax'\np16\nF0.29999999999999999\nsS'ome_i_3'\np17\nI1\nsS'ome_i_2'\np18\nI1\nsS'ome_i_1'\np19\nI1\nsS'ome_i_0'\np20\nI1\nsS'ome_i_5'\np21\nI1\nsS'ome_i_4'\np22\nI1\nsS'bg_i_1'\np23\nI1\nsS'aa_i_1'\np24\nI1\nsS'aa_i_0'\np25\nI1\nsS'aa_i_-1'\np26\nI1\nsS'bm_i_-2'\np27\nI1\nsS'bm_i_-3'\np28\nI1\nsS'bm_i_-1'\np29\nI1\nsS'bm_i_-4'\np30\nI1\nsS'bs_i_2'\np31\nI1\nsS'bs_i_3'\np32\nI1\nsS'bs_i_0'\np33\nI1\nsS'bs_i_1'\np34\nI1\nsS'aa_3'\np35\n(lp36\nsS'aa_2'\np37\n(lp38\nsS'bs_i_4'\np39\nI1\nsS'bs_i_5'\np40\nI1\nsS'aa_-4'\np41\n(lp42\nsS'aa_-3'\np43\n(lp44\nsS'aa_-2'\np45\n(lp46\nsS'aa_-1'\np47\n(lp48\nVc\nasS'rfactorMin'\np49\nF0\nsS'bm_i_4'\np50\nI1\nsS'bm_i_5'\np51\nI1\nsS'bm_i_0'\np52\nI1\nsS'bm_i_1'\np53\nI1\nsS'bm_i_2'\np54\nI1\nsS'bm_i_3'\np55\nI1\nsS'rfactorMax'\np56\nF0.25\nsS'bm_0'\np57\nV<25\np58\nsS'aa_5'\np59\n(lp60\nsS'aa_4'\np61\n(lp62\nsS'resolutionMax'\np63\nF1.2\nsS'aa_1'\np64\n(lp65\nVe\nasS'aa_0'\np66\n(lp67\nVq\nasS'ome_i_-3'\np68\nI1\nsS'ome_i_-2'\np69\nI1\nsS'ome_i_-1'\np70\nI1\nsS'ome_i_-4'\np71\nI1\nsS'ss_0'\np72\n(lp73\nsS'ome_5'\np74\nV<=-90,>=90\np75\nsS'ome_4'\np76\nV<=-90,>=90\np77\nsS'ome_1'\np78\nV<=-90,>=90\np79\nsS'ome_0'\np80\nV<=-90,>=90\np81\nsS'ome_3'\np82\nV<=-90,>=90\np83\nsS'ome_2'\np84\nV<=-90,>=90\np85\nsS'bg_i_-1'\np86\nI1\nsS'bg_i_-2'\np87\nI1\nsS'bg_i_-3'\np88\nI1\nsS'bg_i_-4'\np89\nI1\nsS'bs_i_-4'\np90\nI1\nsS'ss_5'\np91\n(lp92\nsS'ss_4'\np93\n(lp94\nsS'ss_3'\np95\n(lp96\nsS'bs_i_-1'\np97\nI1\nsS'bs_i_-2'\np98\nI1\nsS'bs_i_-3'\np99\nI1\nsS'bg_-4'\np100\nV<25\np101\nsS'ss_-4'\np102\n(lp103\nsS'ss_-3'\np104\n(lp105\nsS'ss_-2'\np106\n(lp107\nsS'ss_-1'\np108\n(lp109\nsS'bg_-1'\np110\nV<25\np111\nsS'ome_-1'\np112\nV<=-90,>=90\np113\nsS'ome_-3'\np114\nV<=-90,>=90\np115\nsS'ome_-2'\np116\nV<=-90,>=90\np117\nsS'ome_-4'\np118\nV<=-90,>=90\np119\nsS'rfreeMin'\np120\nF0\nsS'bm_-1'\np121\nV<25\np122\nsS'bm_-2'\np123\nV<25\np124\nsS'bm_-3'\np125\nV<25\np126\nsS'bm_-4'\np127\nV<25\np128\nsS'bs_4'\np129\nV<25\np130\nsS'bs_5'\np131\nV<25\np132\nsS'bs_0'\np133\nV<25\np134\nsS'bs_1'\np135\nV<25\np136\nsS'bs_2'\np137\nV<25\np138\nsS'bs_3'\np139\nV<25\np140\nsS'bg_0'\np141\nV<25\np142\nsS'bg_1'\np143\nV<25\np144\nsS'bg_2'\np145\nV<25\np146\nsS'bg_3'\np147\nV<25\np148\nsS'bg_4'\np149\nV<25\np150\nsS'bg_5'\np151\nV<25\np152\nsS'bm_4'\np153\nV<25\np154\nsS'bm_5'\np155\nV<25\np156\nsS'bm_2'\np157\nV<25\np158\nsS'bm_3'\np159\nV<25\np160\nsS'residues'\np161\nV3\nsS'bm_1'\np162\nV<25\np163\nsS'bs_-2'\np164\nV<25\np165\nsS'bs_-3'\np166\nV<25\np167\nsS'bs_-1'\np168\nV<25\np169\nsS'bs_-4'\np170\nV<25\np171\nsS'ss_2'\np172\n(lp173\ns.",
+ "tags": "Cys, Gln, Glu"
+ }
+},
+{
+ "pk": 4,
+ "model": "pgd_search.search",
+ "fields": {
+ "dataset_version": "",
+ "description": "Hey there, this is a test search",
+ "title": "Test save",
+ "timestamp": "2015-07-09T11:59:35Z",
+ "isPublic": true,
+ "user": 2,
+ "data_internal": "(dp1\nS'ss_1'\np2\n(lp3\nsS'bg_i_4'\np4\nI1\nsS'bg_i_5'\np5\nI1\nsS'bg_i_2'\np6\nI1\nsS'bg_i_3'\np7\nI1\nsS'bg_i_0'\np8\nI1\nsS'resolutionMin'\np9\nF0\nsS'threshold'\np10\nV25\np11\nsS'bg_-2'\np12\nV<25\np13\nsS'bg_-3'\np14\nV<25\np15\nsS'rfreeMax'\np16\nF0.29999999999999999\nsS'ome_i_3'\np17\nI1\nsS'ome_i_2'\np18\nI1\nsS'ome_i_1'\np19\nI1\nsS'ome_i_0'\np20\nI1\nsS'ome_i_5'\np21\nI1\nsS'ome_i_4'\np22\nI1\nsS'bg_i_1'\np23\nI1\nsS'aa_i_1'\np24\nI1\nsS'aa_i_0'\np25\nI1\nsS'aa_i_-1'\np26\nI1\nsS'bm_i_-2'\np27\nI1\nsS'bm_i_-3'\np28\nI1\nsS'bm_i_-1'\np29\nI1\nsS'bm_i_-4'\np30\nI1\nsS'bs_i_2'\np31\nI1\nsS'bs_i_3'\np32\nI1\nsS'bs_i_0'\np33\nI1\nsS'bs_i_1'\np34\nI1\nsS'aa_3'\np35\n(lp36\nsS'aa_2'\np37\n(lp38\nsS'bs_i_4'\np39\nI1\nsS'bs_i_5'\np40\nI1\nsS'aa_-4'\np41\n(lp42\nsS'aa_-3'\np43\n(lp44\nsS'aa_-2'\np45\n(lp46\nsS'aa_-1'\np47\n(lp48\nVa\nasS'rfactorMin'\np49\nF0\nsS'bm_i_4'\np50\nI1\nsS'bm_i_5'\np51\nI1\nsS'bm_i_0'\np52\nI1\nsS'bm_i_1'\np53\nI1\nsS'bm_i_2'\np54\nI1\nsS'bm_i_3'\np55\nI1\nsS'rfactorMax'\np56\nF0.25\nsS'bm_0'\np57\nV<25\np58\nsS'aa_5'\np59\n(lp60\nsS'aa_4'\np61\n(lp62\nsS'resolutionMax'\np63\nF1.2\nsS'aa_1'\np64\n(lp65\nVr\nasS'aa_0'\np66\n(lp67\nVn\nasS'ome_i_-3'\np68\nI1\nsS'ome_i_-2'\np69\nI1\nsS'ome_i_-1'\np70\nI1\nsS'ome_i_-4'\np71\nI1\nsS'ss_0'\np72\n(lp73\nsS'ome_5'\np74\nV<=-90,>=90\np75\nsS'ome_4'\np76\nV<=-90,>=90\np77\nsS'ome_1'\np78\nV<=-90,>=90\np79\nsS'ome_0'\np80\nV<=-90,>=90\np81\nsS'ome_3'\np82\nV<=-90,>=90\np83\nsS'ome_2'\np84\nV<=-90,>=90\np85\nsS'bg_i_-1'\np86\nI1\nsS'bg_i_-2'\np87\nI1\nsS'bg_i_-3'\np88\nI1\nsS'bg_i_-4'\np89\nI1\nsS'bs_i_-4'\np90\nI1\nsS'ss_5'\np91\n(lp92\nsS'ss_4'\np93\n(lp94\nsS'ss_3'\np95\n(lp96\nsS'bs_i_-1'\np97\nI1\nsS'bs_i_-2'\np98\nI1\nsS'bs_i_-3'\np99\nI1\nsS'bg_-4'\np100\nV<25\np101\nsS'ss_-4'\np102\n(lp103\nsS'ss_-3'\np104\n(lp105\nsS'ss_-2'\np106\n(lp107\nsS'ss_-1'\np108\n(lp109\nsS'bg_-1'\np110\nV<25\np111\nsS'ome_-1'\np112\nV<=-90,>=90\np113\nsS'ome_-3'\np114\nV<=-90,>=90\np115\nsS'ome_-2'\np116\nV<=-90,>=90\np117\nsS'ome_-4'\np118\nV<=-90,>=90\np119\nsS'rfreeMin'\np120\nF0\nsS'bm_-1'\np121\nV<25\np122\nsS'bm_-2'\np123\nV<25\np124\nsS'bm_-3'\np125\nV<25\np126\nsS'bm_-4'\np127\nV<25\np128\nsS'bs_4'\np129\nV<25\np130\nsS'bs_5'\np131\nV<25\np132\nsS'bs_0'\np133\nV<25\np134\nsS'bs_1'\np135\nV<25\np136\nsS'bs_2'\np137\nV<25\np138\nsS'bs_3'\np139\nV<25\np140\nsS'bg_0'\np141\nV<25\np142\nsS'bg_1'\np143\nV<25\np144\nsS'bg_2'\np145\nV<25\np146\nsS'bg_3'\np147\nV<25\np148\nsS'bg_4'\np149\nV<25\np150\nsS'bg_5'\np151\nV<25\np152\nsS'bm_4'\np153\nV<25\np154\nsS'bm_5'\np155\nV<25\np156\nsS'bm_2'\np157\nV<25\np158\nsS'bm_3'\np159\nV<25\np160\nsS'residues'\np161\nV3\nsS'bm_1'\np162\nV<25\np163\nsS'bs_-2'\np164\nV<25\np165\nsS'bs_-3'\np166\nV<25\np167\nsS'bs_-1'\np168\nV<25\np169\nsS'bs_-4'\np170\nV<25\np171\nsS'ss_2'\np172\n(lp173\ns.",
+ "tags": "Ala, Asn, Arg"
+ }
+},
+{
+ "pk": 5,
+ "model": "pgd_search.search",
+ "fields": {
+ "dataset_version": "",
+ "description": "Hey there, this is again a test search",
+ "title": "Test Save 2",
+ "timestamp": "2015-07-09T12:08:23Z",
+ "isPublic": true,
+ "user": 2,
+ "data_internal": "(dp1\nS'ss_1'\np2\n(lp3\nsS'bg_i_4'\np4\nI1\nsS'bg_i_5'\np5\nI1\nsS'bg_i_2'\np6\nI1\nsS'bg_i_3'\np7\nI1\nsS'bg_i_0'\np8\nI1\nsS'resolutionMin'\np9\nF0\nsS'threshold'\np10\nV25\np11\nsS'bg_-2'\np12\nV<25\np13\nsS'bg_-3'\np14\nV<25\np15\nsS'rfreeMax'\np16\nF0.29999999999999999\nsS'ome_i_3'\np17\nI1\nsS'ome_i_2'\np18\nI1\nsS'ome_i_1'\np19\nI1\nsS'ome_i_0'\np20\nI1\nsS'ome_i_5'\np21\nI1\nsS'ome_i_4'\np22\nI1\nsS'bg_i_1'\np23\nI1\nsS'aa_i_1'\np24\nI1\nsS'aa_i_0'\np25\nI1\nsS'aa_i_-1'\np26\nI1\nsS'bm_i_-2'\np27\nI1\nsS'bm_i_-3'\np28\nI1\nsS'bm_i_-1'\np29\nI1\nsS'bm_i_-4'\np30\nI1\nsS'bs_i_2'\np31\nI1\nsS'bs_i_3'\np32\nI1\nsS'bs_i_0'\np33\nI1\nsS'bs_i_1'\np34\nI1\nsS'aa_3'\np35\n(lp36\nsS'aa_2'\np37\n(lp38\nsS'bs_i_4'\np39\nI1\nsS'bs_i_5'\np40\nI1\nsS'aa_-4'\np41\n(lp42\nsS'aa_-3'\np43\n(lp44\nsS'aa_-2'\np45\n(lp46\nsS'aa_-1'\np47\n(lp48\nVc\nasS'rfactorMin'\np49\nF0\nsS'bm_i_4'\np50\nI1\nsS'bm_i_5'\np51\nI1\nsS'bm_i_0'\np52\nI1\nsS'bm_i_1'\np53\nI1\nsS'bm_i_2'\np54\nI1\nsS'bm_i_3'\np55\nI1\nsS'rfactorMax'\np56\nF0.25\nsS'bm_0'\np57\nV<25\np58\nsS'aa_5'\np59\n(lp60\nsS'aa_4'\np61\n(lp62\nsS'resolutionMax'\np63\nF1.2\nsS'aa_1'\np64\n(lp65\nVn\nasS'aa_0'\np66\n(lp67\nVd\nasS'ome_i_-3'\np68\nI1\nsS'ome_i_-2'\np69\nI1\nsS'ome_i_-1'\np70\nI1\nsS'ome_i_-4'\np71\nI1\nsS'ss_0'\np72\n(lp73\nsS'ome_5'\np74\nV<=-90,>=90\np75\nsS'ome_4'\np76\nV<=-90,>=90\np77\nsS'ome_1'\np78\nV<=-90,>=90\np79\nsS'ome_0'\np80\nV<=-90,>=90\np81\nsS'ome_3'\np82\nV<=-90,>=90\np83\nsS'ome_2'\np84\nV<=-90,>=90\np85\nsS'bg_i_-1'\np86\nI1\nsS'bg_i_-2'\np87\nI1\nsS'bg_i_-3'\np88\nI1\nsS'bg_i_-4'\np89\nI1\nsS'bs_i_-4'\np90\nI1\nsS'ss_5'\np91\n(lp92\nsS'ss_4'\np93\n(lp94\nsS'ss_3'\np95\n(lp96\nsS'bs_i_-1'\np97\nI1\nsS'bs_i_-2'\np98\nI1\nsS'bs_i_-3'\np99\nI1\nsS'bg_-4'\np100\nV<25\np101\nsS'ss_-4'\np102\n(lp103\nsS'ss_-3'\np104\n(lp105\nsS'ss_-2'\np106\n(lp107\nsS'ss_-1'\np108\n(lp109\nsS'bg_-1'\np110\nV<25\np111\nsS'ome_-1'\np112\nV<=-90,>=90\np113\nsS'ome_-3'\np114\nV<=-90,>=90\np115\nsS'ome_-2'\np116\nV<=-90,>=90\np117\nsS'ome_-4'\np118\nV<=-90,>=90\np119\nsS'rfreeMin'\np120\nF0\nsS'bm_-1'\np121\nV<25\np122\nsS'bm_-2'\np123\nV<25\np124\nsS'bm_-3'\np125\nV<25\np126\nsS'bm_-4'\np127\nV<25\np128\nsS'bs_4'\np129\nV<25\np130\nsS'bs_5'\np131\nV<25\np132\nsS'bs_0'\np133\nV<25\np134\nsS'bs_1'\np135\nV<25\np136\nsS'bs_2'\np137\nV<25\np138\nsS'bs_3'\np139\nV<25\np140\nsS'bg_0'\np141\nV<25\np142\nsS'bg_1'\np143\nV<25\np144\nsS'bg_2'\np145\nV<25\np146\nsS'bg_3'\np147\nV<25\np148\nsS'bg_4'\np149\nV<25\np150\nsS'bg_5'\np151\nV<25\np152\nsS'bm_4'\np153\nV<25\np154\nsS'bm_5'\np155\nV<25\np156\nsS'bm_2'\np157\nV<25\np158\nsS'bm_3'\np159\nV<25\np160\nsS'residues'\np161\nV3\nsS'bm_1'\np162\nV<25\np163\nsS'bs_-2'\np164\nV<25\np165\nsS'bs_-3'\np166\nV<25\np167\nsS'bs_-1'\np168\nV<25\np169\nsS'bs_-4'\np170\nV<25\np171\nsS'ss_2'\np172\n(lp173\ns.",
+ "tags": "Cys, Asp, Asn"
+ }
+},
+{
+ "pk": 6,
+ "model": "pgd_search.search",
+ "fields": {
+ "dataset_version": "",
+ "description": "Hey there, this is again a test search",
+ "title": "Test save 3",
+ "timestamp": "2015-07-09T12:08:59Z",
+ "isPublic": false,
+ "user": 2,
+ "data_internal": "(dp1\nS'ss_1'\np2\n(lp3\nsS'bg_i_4'\np4\nI1\nsS'bg_i_5'\np5\nI1\nsS'bg_i_2'\np6\nI1\nsS'bg_i_3'\np7\nI1\nsS'bg_i_0'\np8\nI1\nsS'resolutionMin'\np9\nF0\nsS'threshold'\np10\nV25\np11\nsS'bg_-2'\np12\nV<25\np13\nsS'bg_-3'\np14\nV<25\np15\nsS'rfreeMax'\np16\nF0.29999999999999999\nsS'ome_i_3'\np17\nI1\nsS'ome_i_2'\np18\nI1\nsS'ome_i_1'\np19\nI1\nsS'ome_i_0'\np20\nI1\nsS'ome_i_5'\np21\nI1\nsS'ome_i_4'\np22\nI1\nsS'bg_i_1'\np23\nI1\nsS'aa_i_1'\np24\nI1\nsS'aa_i_0'\np25\nI1\nsS'aa_i_-1'\np26\nI1\nsS'bm_i_-2'\np27\nI1\nsS'bm_i_-3'\np28\nI1\nsS'bm_i_-1'\np29\nI1\nsS'bm_i_-4'\np30\nI1\nsS'bs_i_2'\np31\nI1\nsS'bs_i_3'\np32\nI1\nsS'bs_i_0'\np33\nI1\nsS'bs_i_1'\np34\nI1\nsS'aa_3'\np35\n(lp36\nsS'aa_2'\np37\n(lp38\nsS'bs_i_4'\np39\nI1\nsS'bs_i_5'\np40\nI1\nsS'aa_-4'\np41\n(lp42\nsS'aa_-3'\np43\n(lp44\nsS'aa_-2'\np45\n(lp46\nsS'aa_-1'\np47\n(lp48\nVe\nasS'rfactorMin'\np49\nF0\nsS'bm_i_4'\np50\nI1\nsS'bm_i_5'\np51\nI1\nsS'bm_i_0'\np52\nI1\nsS'bm_i_1'\np53\nI1\nsS'bm_i_2'\np54\nI1\nsS'bm_i_3'\np55\nI1\nsS'rfactorMax'\np56\nF0.25\nsS'bm_0'\np57\nV<25\np58\nsS'aa_5'\np59\n(lp60\nsS'aa_4'\np61\n(lp62\nsS'resolutionMax'\np63\nF1.2\nsS'aa_1'\np64\n(lp65\nVc\nasS'aa_0'\np66\n(lp67\nVq\nasS'ome_i_-3'\np68\nI1\nsS'ome_i_-2'\np69\nI1\nsS'ome_i_-1'\np70\nI1\nsS'ome_i_-4'\np71\nI1\nsS'ss_0'\np72\n(lp73\nsS'ome_5'\np74\nV<=-90,>=90\np75\nsS'ome_4'\np76\nV<=-90,>=90\np77\nsS'ome_1'\np78\nV<=-90,>=90\np79\nsS'ome_0'\np80\nV<=-90,>=90\np81\nsS'ome_3'\np82\nV<=-90,>=90\np83\nsS'ome_2'\np84\nV<=-90,>=90\np85\nsS'bg_i_-1'\np86\nI1\nsS'bg_i_-2'\np87\nI1\nsS'bg_i_-3'\np88\nI1\nsS'bg_i_-4'\np89\nI1\nsS'bs_i_-4'\np90\nI1\nsS'ss_5'\np91\n(lp92\nsS'ss_4'\np93\n(lp94\nsS'ss_3'\np95\n(lp96\nsS'bs_i_-1'\np97\nI1\nsS'bs_i_-2'\np98\nI1\nsS'bs_i_-3'\np99\nI1\nsS'bg_-4'\np100\nV<25\np101\nsS'ss_-4'\np102\n(lp103\nsS'ss_-3'\np104\n(lp105\nsS'ss_-2'\np106\n(lp107\nsS'ss_-1'\np108\n(lp109\nsS'bg_-1'\np110\nV<25\np111\nsS'ome_-1'\np112\nV<=-90,>=90\np113\nsS'ome_-3'\np114\nV<=-90,>=90\np115\nsS'ome_-2'\np116\nV<=-90,>=90\np117\nsS'ome_-4'\np118\nV<=-90,>=90\np119\nsS'rfreeMin'\np120\nF0\nsS'bm_-1'\np121\nV<25\np122\nsS'bm_-2'\np123\nV<25\np124\nsS'bm_-3'\np125\nV<25\np126\nsS'bm_-4'\np127\nV<25\np128\nsS'bs_4'\np129\nV<25\np130\nsS'bs_5'\np131\nV<25\np132\nsS'bs_0'\np133\nV<25\np134\nsS'bs_1'\np135\nV<25\np136\nsS'bs_2'\np137\nV<25\np138\nsS'bs_3'\np139\nV<25\np140\nsS'bg_0'\np141\nV<25\np142\nsS'bg_1'\np143\nV<25\np144\nsS'bg_2'\np145\nV<25\np146\nsS'bg_3'\np147\nV<25\np148\nsS'bg_4'\np149\nV<25\np150\nsS'bg_5'\np151\nV<25\np152\nsS'bm_4'\np153\nV<25\np154\nsS'bm_5'\np155\nV<25\np156\nsS'bm_2'\np157\nV<25\np158\nsS'bm_3'\np159\nV<25\np160\nsS'residues'\np161\nV3\nsS'bm_1'\np162\nV<25\np163\nsS'bs_-2'\np164\nV<25\np165\nsS'bs_-3'\np166\nV<25\np167\nsS'bs_-1'\np168\nV<25\np169\nsS'bs_-4'\np170\nV<25\np171\nsS'ss_2'\np172\n(lp173\ns.",
+ "tags": "Glu, Gln, Cys"
+ }
+}
+]
diff --git a/pgd_core/forms.py b/pgd_core/forms.py
index 6849d2d..992f65c 100644
--- a/pgd_core/forms.py
+++ b/pgd_core/forms.py
@@ -34,4 +34,16 @@ class EditForm(forms.Form):
widget=forms.TextInput(attrs={'placeholder': 'first_name'}))
last_name = forms.CharField(label="Last Name",
- widget=forms.TextInput(attrs={'placeholder': 'Last Name'}))
\ No newline at end of file
+ widget=forms.TextInput(attrs={'placeholder': 'Last Name'}))
+
+class SavedSearchesForm(forms.Form):
+
+ choices=[('GlobalSearch','Global Search'),
+ ('LocalSearch','Local Search')]
+
+ query = forms.CharField(label="Search SavedSearches",
+ widget=forms.TextInput(attrs={'placeholder' : 'Search'}))
+
+ search_type = forms.ChoiceField(required = True, label = "Search Type",
+ choices=choices,
+ widget=forms.RadioSelect(), initial='GlobalSearch')
\ No newline at end of file
diff --git a/pgd_core/templates/profile.html b/pgd_core/templates/profile.html
index 1ffabd2..761f4eb 100644
--- a/pgd_core/templates/profile.html
+++ b/pgd_core/templates/profile.html
@@ -5,6 +5,20 @@
{% block content %}
Welcome, {{full_name}}
+
+
+
+
+
@@ -35,33 +49,54 @@
| Saved searches |
+
+
-
+
+
|
Time stamp
|
+
+ Tags
+ |
Description
|
Title
|
+
+
+
+
+
+ |
- Public ?
+ Public ?
|
+
+
{% for attr in saved_search %}
-
+
| {{ attr.timestamp }} |
+ {{ attr.tags }} |
+
{{ attr.description }} |
{{ attr.title }} |
- {{ attr.isPublic }} |
+
+
+ |
+
+ {{ attr.isPublic }} |
+
{% endfor %}
@@ -70,14 +105,14 @@
|
-
+ table {
+ border-collapse: collapse;
+ }
+ .sSearch{
+ border: 1px solid black;
+ }
+
+
{% endblock %}
diff --git a/pgd_core/templates/saved-search-match.html b/pgd_core/templates/saved-search-match.html
new file mode 100644
index 0000000..ebf6712
--- /dev/null
+++ b/pgd_core/templates/saved-search-match.html
@@ -0,0 +1,79 @@
+{% extends 'base.html' %}
+
+{% block content %}
+
+ Matched Searches
+
+
+
+
+
+
+ |
+ Time stamp
+ |
+
+
+ Tags
+ |
+
+
+ Description
+ |
+
+
+ Title
+ |
+
+
+
+ |
+
+
+ User
+ |
+
+
+ Public ?
+ |
+
+
+
+
+ {% for var in matches %}
+
+
+
+ | {{ var.timestamp }} |
+
+ {{ var.tags }} |
+
+ {{ var.description }} |
+
+ {{ var.title }} |
+
+
+
+ |
+
+ {{ var.user.username }} |
+
+ {{ var.isPublic }} |
+
+
+
+
+ {% endfor %}
+
+
+
+{% endblock %}
\ No newline at end of file
diff --git a/pgd_core/templates/saved-search-notfound.html b/pgd_core/templates/saved-search-notfound.html
new file mode 100644
index 0000000..7ffedf8
--- /dev/null
+++ b/pgd_core/templates/saved-search-notfound.html
@@ -0,0 +1,4 @@
+{% extends "base.html" %}
+{% block content %}
+Sorry, the saved Search that you're trying to search does not exist.
+{% endblock %}
\ No newline at end of file
diff --git a/pgd_core/tests.py b/pgd_core/tests.py
index 719bc69..b376990 100644
--- a/pgd_core/tests.py
+++ b/pgd_core/tests.py
@@ -13,7 +13,7 @@
class RegistrationTestCase(TestCase):
- fixtures = ['pgd_core']
+ fixtures = ['users']
default_url = "http://testserver"
test_email = {'email' : 'email@example.org'}
test_credentials = {'username':'test_user', 'password':'hello'}
@@ -93,7 +93,7 @@ def test_save_search(self):
post_credentials = test_client.post(get_profile.redirect_chain[-1][0], self.test_credentials, follow=True)
self.assertEqual(post_credentials.status_code, 200)
profile_page = test_client.get(reverse('generic_profile', args=('test_user',)))
- self.assertIn('False | ' , profile_page.content)
+ self.assertIn(' False | ' , profile_page.content)
def test_search_user(self):
@@ -110,3 +110,52 @@ def test_search_user(self):
#No matches
search_none = test_client.get(reverse('user-search'), {'q' : 'whatever'}, redirect=True)
self.assertEqual(search_none['Location'], self.default_url+reverse('notfound'))
+
+ def test_search_saved_searches(self):
+
+ test_client = Client()
+
+ #search before login, searches for some tag, checks if..
+ #The tag that is not related to the search is not present
+
+ #Local Search
+ search = test_client.post(reverse('generic_profile',
+ args=('test_user',)), {'query' : 'Asp, cys', 'search_type' : 'LocalSearch'},
+ follow=True)
+
+ #Asserts if non-Public search is not listed
+ self.assertNotIn('False | ' , search.content)
+ self.assertNotIn(' Ala, Asn, Arg | ', search.content)
+
+ #Global Search
+ search = test_client.post(reverse('generic_profile',
+ args=('test_user',)), {'query' : 'Asp, cys', 'search_type' : 'GlobalSearch'},
+ follow=True)
+
+ #Asserts if non-Public search is not listed
+ self.assertNotIn('False | ' , search.content)
+ self.assertNotIn(' Ala, Asn, Arg | ', search.content)
+ #Checks for presence of User: Test
+ self.assertIn(' test | ', search.content)
+
+ #Search After login
+ get_profile = test_client.get(reverse('user_profile'), follow=True)
+ self.assertEqual(get_profile.status_code, 200)
+ post_credentials = test_client.post(get_profile.redirect_chain[-1][0],
+ self.test_credentials, follow=True)
+ self.assertEqual(post_credentials.status_code, 200)
+ #Local Search
+ local_search_result = test_client.post( post_credentials.redirect_chain[-1][0],
+ {'query' : 'Gln, Glu', 'search_type' : 'LocalSearch'}, follow=True)
+
+ self.assertIn('False | ' , local_search_result.content)
+ self.assertIn(' Glu, Gln, Cys | ', local_search_result.content)
+
+ #Global Search
+ global_search_result = test_client.post( post_credentials.redirect_chain[-1][0],
+ {'query' : 'Cys, Asp', 'search_type' : 'GlobalSearch'}, follow=True)
+
+ self.assertIn(' Cys, Asp, Asn | ', global_search_result.content)
+
+ #Checks for presence of User: Test
+ self.assertIn(' test | ', global_search_result.content)
diff --git a/pgd_core/urls.py b/pgd_core/urls.py
index 1a49276..4fab551 100644
--- a/pgd_core/urls.py
+++ b/pgd_core/urls.py
@@ -3,7 +3,7 @@
from django.contrib.auth import views as auth_views
from django.core.urlresolvers import reverse_lazy
from forms import UserRegistrationForm
-from views import MyRegistrationView , profile_view, edit_profile_view, get_profile_view, search, notfound
+from views import MyRegistrationView , profile_view, edit_profile_view, get_profile_view, search, notfound, savedSearches
from registration.backends.default.views import RegistrationView
urlpatterns = patterns('',
@@ -56,4 +56,5 @@
url(r'^profile-edit/$', edit_profile_view, name='user_profile_edit'),
url(r'^search/$', search, name='user-search'),
url(r'^notfound/$', notfound ,name='notfound' ),
+ url(r'^savedsearches/(?P[a-zA-Z_\s@\+\.,-]+)/(?P[a-zA-Z_\s@\+\.,-]+)/(?P[a-zA-Z_\s@\+\.,-]+)$', savedSearches, name='savedsearches'),
)
\ No newline at end of file
diff --git a/pgd_core/views.py b/pgd_core/views.py
index e3ee460..7b5000d 100644
--- a/pgd_core/views.py
+++ b/pgd_core/views.py
@@ -5,9 +5,11 @@
from django.contrib.auth.models import User
from django.contrib.auth.decorators import login_required
from registration.backends.default.views import RegistrationView
-from forms import UserRegistrationForm as MyCustomRegistrationForm, EditForm
+from forms import UserRegistrationForm as MyCustomRegistrationForm, EditForm, SavedSearchesForm
from pgd_search.models import Search
from django.db.models import Q
+from functools import reduce
+from operator import and_, or_
class MyRegistrationView(RegistrationView):
@@ -20,27 +22,6 @@ def register(self, request, form):
new_user.save()
return new_user
-
-@login_required(login_url='/accounts/login')
-def profile_view(request) :
-
- if request.user.is_active :
- #Fetch information for this user from RegProfile
- prof_details = {}
-
- prof_details['first_name'] = request.user.first_name
- prof_details['last_name'] = request.user.last_name
- prof_details['email'] = request.user.email
- prof_details['user_name'] = request.user.username
- prof_details['full_name'] = request.user.get_full_name()
- search = Search.objects.all().filter(user=request.user)
- prof_details['saved_search'] = search
-
- return render(request, 'profile.html', prof_details)
- else :
- return redirect('/accounts/login')
-
-
@login_required(login_url='/accounts/login')
def edit_profile_view(request):
@@ -60,33 +41,78 @@ def edit_profile_view(request):
return render(request, 'edit_profile.html', {'form' : form,})
-def get_profile_view(request, username):
+@login_required(login_url='/accounts/login')
+def profile_view(request) :
-
- try:
- user = User.objects.get(username=username)
- prof_details = {}
- prof_details['first_name'] = user.first_name
- prof_details['last_name'] = user.last_name
- prof_details['email'] = user.email
- prof_details['user_name'] = username
+ if request.user.is_active :
+ if request.method == 'POST':
+ form = SavedSearchesForm(request.POST)
+ if form.is_valid() :
+ params = dict(username=request.user.username,
+ query=form.cleaned_data['query'],
+ search_type=form.cleaned_data['search_type'])
+ return redirect('savedsearches', **params)
- if request.user.username == username :
- search = Search.objects.all().filter(user=request.user)
else :
- search = Search.objects.filter(
- user=User.objects.get(username=username)).all().exclude(isPublic=False)
-
- prof_details['saved_search'] = search
- if request.user.is_active :
+ #Fetch information for this user from RegProfile
+ form = SavedSearchesForm()
+ prof_details = {}
+
+ prof_details['first_name'] = request.user.first_name
+ prof_details['last_name'] = request.user.last_name
+ prof_details['email'] = request.user.email
+ prof_details['user_name'] = request.user.username
prof_details['full_name'] = request.user.get_full_name()
- else :
- prof_details['full_name'] = ''
+ search = Search.objects.all().filter(user=request.user)
+ prof_details['saved_search'] = search
+ prof_details['form'] = form
+ return render(request, 'profile.html', prof_details)
+ else :
+ return redirect('/accounts/login')
- return render(request, 'profile.html', prof_details)
+
+
+def get_profile_view(request, username):
+
+ if request.method == 'POST':
+
+ form = SavedSearchesForm(request.POST)
+ if form.is_valid() :
+ params = dict(username=username,
+ query=form.cleaned_data['query'],
+ search_type=form.cleaned_data['search_type'])
+ return redirect('savedsearches', **params)
+
+ else :
+
+ form = SavedSearchesForm()
- except Exception, e:
- return redirect(reverse('notfound'))
+ try:
+ user = User.objects.get(username=username)
+ prof_details = {}
+ prof_details['first_name'] = user.first_name
+ prof_details['last_name'] = user.last_name
+ prof_details['email'] = user.email
+ prof_details['user_name'] = username
+
+ if request.user.username == username :
+ search = Search.objects.all().filter(user=request.user)
+ else :
+ search = Search.objects.filter(
+ user=User.objects.get(username=username)).all().exclude(isPublic=False)
+
+ prof_details['saved_search'] = search
+ if request.user.is_active :
+ prof_details['full_name'] = request.user.get_full_name()
+ else :
+ prof_details['full_name'] = ''
+
+ prof_details['form'] = form
+
+ return render(request, 'profile.html', prof_details)
+
+ except Exception, e:
+ return redirect(reverse('notfound'))
def search(request):
@@ -112,4 +138,35 @@ def search(request):
def notfound(request) :
- return render(request, 'usernotfound.html')
\ No newline at end of file
+ return render(request, 'usernotfound.html')
+
+#View for displaying the result of searching among saved searches
+def savedSearches(request, username, query, search_type) :
+
+
+ match_list = []
+ query_search = query.split(',')
+
+ if search_type == "GlobalSearch" :
+
+ for i in query_search :
+ if request.user.username == username :
+ match_list.append(Search.objects.filter(Q(tags__icontains=i.strip())))
+ else :
+ match_list.append(Search.objects.filter(Q(tags__icontains=i.strip())).exclude(isPublic=False))
+
+ else :
+ user = User.objects.get(username=username)
+ for i in query_search :
+ if request.user.username == username :
+ match_list.append(Search.objects.filter( Q(user=user) , Q(tags__icontains=i.strip())))
+ else :
+ match_list.append(Search.objects.filter( Q(user=user) ,
+ Q(tags__icontains=i.strip())).exclude(isPublic=False))
+
+ combined_and_querysets = reduce(or_, match_list[1:], match_list[0])
+
+ if combined_and_querysets :
+ return render(request, 'saved-search-match.html', {'matches' : combined_and_querysets})
+ else :
+ return render(request, 'saved-search-notfound.html')
\ No newline at end of file
diff --git a/pgd_search/models.py b/pgd_search/models.py
index 1c7335f..28c8056 100644
--- a/pgd_search/models.py
+++ b/pgd_search/models.py
@@ -54,6 +54,7 @@ class Search(models.Model):
description = models.CharField(max_length='5000')
user = models.ForeignKey(User, null=True)
data_internal = models.TextField()
+ tags = models.CharField(max_length=100)
__data = None
@property
@@ -557,4 +558,5 @@ class saveSearchForm(forms.Form):
description = forms.CharField(label='Description', widget=forms.Textarea)
isPublic = forms.BooleanField(label='Publically Viewable',required=False)
id = forms.IntegerField(None, widget=forms.HiddenInput, required=False)
-
+ tags = forms.CharField(label='Tags', required=False,
+ help_text='A Tag that helps in searching among saved searches')
\ No newline at end of file
diff --git a/pgd_search/search/views.py b/pgd_search/search/views.py
index 5b3005e..93b2cd7 100644
--- a/pgd_search/search/views.py
+++ b/pgd_search/search/views.py
@@ -278,6 +278,7 @@ def saveSearch(request,search_id=None):
search.user=request.user
search.timestamp=datetime.now()
search.isPublic = data['isPublic']
+ search.tags = data['tags']
search.save()
return HttpResponseRedirect('%s/search/saved/' % settings.SITE_ROOT)
diff --git a/pgd_search/templates/saveSearch.html b/pgd_search/templates/saveSearch.html
index eb1a289..9225947 100644
--- a/pgd_search/templates/saveSearch.html
+++ b/pgd_search/templates/saveSearch.html
@@ -113,6 +113,12 @@
By default, all searches are private and inaccessible to others.
+
+ {{ form.tags.label}} {{ form.tags }}
+
+ Helps in searching among the saved searches by filtering out based on these tags.
+ |
+
|