diff --git a/fabfile.py b/fabfile.py index 18a53bb..c6fd1c1 100644 --- a/fabfile.py +++ b/fabfile.py @@ -15,4 +15,9 @@ def make_migrations(): run_manage('makemigrations') def requirements(): - local('/home/vagrant/.virtualenvs/le-code-test/bin/pip install -r requirements.txt ') \ No newline at end of file + local('/home/vagrant/.virtualenvs/le-code-test/bin/pip install -r requirements.txt ') + +# clear down DB and load sample fixtures +def load_sample_data(): + run_manage('flush') # prompts for confirmation + run_manage('loaddata fixtures/test_fixtures.json') diff --git a/testsite/.gitignore b/testsite/.gitignore new file mode 100644 index 0000000..0d20b64 --- /dev/null +++ b/testsite/.gitignore @@ -0,0 +1 @@ +*.pyc diff --git a/testsite/dog-aromatherapy.jpg b/testsite/dog-aromatherapy.jpg new file mode 100644 index 0000000..1c25a4f Binary files /dev/null and b/testsite/dog-aromatherapy.jpg differ diff --git a/testsite/fixtures/test_fixtures.json b/testsite/fixtures/test_fixtures.json new file mode 100644 index 0000000..d5bd655 --- /dev/null +++ b/testsite/fixtures/test_fixtures.json @@ -0,0 +1 @@ +[{"fields": {"model": "logentry", "name": "log entry", "app_label": "admin"}, "model": "contenttypes.contenttype", "pk": 1}, {"fields": {"model": "permission", "name": "permission", "app_label": "auth"}, "model": "contenttypes.contenttype", "pk": 2}, {"fields": {"model": "group", "name": "group", "app_label": "auth"}, "model": "contenttypes.contenttype", "pk": 3}, {"fields": {"model": "user", "name": "user", "app_label": "auth"}, "model": "contenttypes.contenttype", "pk": 4}, {"fields": {"model": "contenttype", "name": "content type", "app_label": "contenttypes"}, "model": "contenttypes.contenttype", "pk": 5}, {"fields": {"model": "session", "name": "session", "app_label": "sessions"}, "model": "contenttypes.contenttype", "pk": 6}, {"fields": {"model": "stream", "name": "stream", "app_label": "stream"}, "model": "contenttypes.contenttype", "pk": 7}, {"fields": {"model": "photoitem", "name": "photo item", "app_label": "items"}, "model": "contenttypes.contenttype", "pk": 8}, {"fields": {"model": "tweetitem", "name": "tweet item", "app_label": "items"}, "model": "contenttypes.contenttype", "pk": 9}, {"fields": {"expire_date": "2016-04-21T18:18:19.227Z", "session_data": "MzkwYTA0MGZmMDBjMTUyY2NiOWRjNDlkY2ZmOTI4N2ExNTMxNjhkYzp7Il9hdXRoX3VzZXJfaGFzaCI6IjEwMjE5NTgwNDY5MDYwNWU0NWQzMmU4YjdjODhmZmIyM2VhNTVhOGYiLCJfYXV0aF91c2VyX2JhY2tlbmQiOiJkamFuZ28uY29udHJpYi5hdXRoLmJhY2tlbmRzLk1vZGVsQmFja2VuZCIsIl9hdXRoX3VzZXJfaWQiOjF9"}, "model": "sessions.session", "pk": "x1su0hhwo5dh54f92e0jcykkf6qi8qlc"}, {"fields": {"codename": "add_logentry", "name": "Can add log entry", "content_type": 1}, "model": "auth.permission", "pk": 1}, {"fields": {"codename": "change_logentry", "name": "Can change log entry", "content_type": 1}, "model": "auth.permission", "pk": 2}, {"fields": {"codename": "delete_logentry", "name": "Can delete log entry", "content_type": 1}, "model": "auth.permission", "pk": 3}, {"fields": {"codename": "add_permission", "name": "Can add permission", "content_type": 2}, "model": "auth.permission", "pk": 4}, {"fields": {"codename": "change_permission", "name": "Can change permission", "content_type": 2}, "model": "auth.permission", "pk": 5}, {"fields": {"codename": "delete_permission", "name": "Can delete permission", "content_type": 2}, "model": "auth.permission", "pk": 6}, {"fields": {"codename": "add_group", "name": "Can add group", "content_type": 3}, "model": "auth.permission", "pk": 7}, {"fields": {"codename": "change_group", "name": "Can change group", "content_type": 3}, "model": "auth.permission", "pk": 8}, {"fields": {"codename": "delete_group", "name": "Can delete group", "content_type": 3}, "model": "auth.permission", "pk": 9}, {"fields": {"codename": "add_user", "name": "Can add user", "content_type": 4}, "model": "auth.permission", "pk": 10}, {"fields": {"codename": "change_user", "name": "Can change user", "content_type": 4}, "model": "auth.permission", "pk": 11}, {"fields": {"codename": "delete_user", "name": "Can delete user", "content_type": 4}, "model": "auth.permission", "pk": 12}, {"fields": {"codename": "add_contenttype", "name": "Can add content type", "content_type": 5}, "model": "auth.permission", "pk": 13}, {"fields": {"codename": "change_contenttype", "name": "Can change content type", "content_type": 5}, "model": "auth.permission", "pk": 14}, {"fields": {"codename": "delete_contenttype", "name": "Can delete content type", "content_type": 5}, "model": "auth.permission", "pk": 15}, {"fields": {"codename": "add_session", "name": "Can add session", "content_type": 6}, "model": "auth.permission", "pk": 16}, {"fields": {"codename": "change_session", "name": "Can change session", "content_type": 6}, "model": "auth.permission", "pk": 17}, {"fields": {"codename": "delete_session", "name": "Can delete session", "content_type": 6}, "model": "auth.permission", "pk": 18}, {"fields": {"codename": "add_stream", "name": "Can add stream", "content_type": 7}, "model": "auth.permission", "pk": 19}, {"fields": {"codename": "change_stream", "name": "Can change stream", "content_type": 7}, "model": "auth.permission", "pk": 20}, {"fields": {"codename": "delete_stream", "name": "Can delete stream", "content_type": 7}, "model": "auth.permission", "pk": 21}, {"fields": {"codename": "add_photoitem", "name": "Can add photo item", "content_type": 8}, "model": "auth.permission", "pk": 22}, {"fields": {"codename": "change_photoitem", "name": "Can change photo item", "content_type": 8}, "model": "auth.permission", "pk": 23}, {"fields": {"codename": "delete_photoitem", "name": "Can delete photo item", "content_type": 8}, "model": "auth.permission", "pk": 24}, {"fields": {"codename": "add_tweetitem", "name": "Can add tweet item", "content_type": 9}, "model": "auth.permission", "pk": 25}, {"fields": {"codename": "change_tweetitem", "name": "Can change tweet item", "content_type": 9}, "model": "auth.permission", "pk": 26}, {"fields": {"codename": "delete_tweetitem", "name": "Can delete tweet item", "content_type": 9}, "model": "auth.permission", "pk": 27}, {"fields": {"username": "admin", "first_name": "", "last_name": "", "is_active": true, "is_superuser": true, "is_staff": true, "last_login": "2016-04-07T18:18:19.224Z", "groups": [], "user_permissions": [], "password": "pbkdf2_sha256$12000$3UcNRpsp3RRD$HU5Knq5ArCxeH6Wv8c8URAwGXY97LZNCuCO6NTzl6yo=", "email": "seantcasey@gmail.com", "date_joined": "2016-04-07T18:18:02.516Z"}, "model": "auth.user", "pk": 1}, {"fields": {"created_at": "2016-04-07T18:28:35Z", "photo_item": null, "user": 1, "tweet_item": 3}, "model": "stream.stream", "pk": 3}, {"fields": {"created_at": "2016-04-07T18:29:11Z", "photo_item": null, "user": 1, "tweet_item": 1}, "model": "stream.stream", "pk": 4}, {"fields": {"created_at": "2016-04-07T18:46:09Z", "photo_item": 3, "user": 1, "tweet_item": null}, "model": "stream.stream", "pk": 6}, {"fields": {"created_at": "2016-04-07T20:28:04Z", "photo_item": null, "user": 1, "tweet_item": 4}, "model": "stream.stream", "pk": 7}, {"fields": {"deleted": false, "created_at": "2016-04-07T18:50:23Z", "user": 1, "image": "./dog-aromatherapy.jpg"}, "model": "items.photoitem", "pk": 3}, {"fields": {"deleted": false, "text": "This is a tweet", "created_at": "2016-04-07T18:19:09Z", "user": 1}, "model": "items.tweetitem", "pk": 1}, {"fields": {"deleted": true, "text": "This is a tweet", "created_at": "2016-04-07T18:21:33Z", "user": 1}, "model": "items.tweetitem", "pk": 2}, {"fields": {"deleted": false, "text": "Another one", "created_at": "2016-04-07T18:21:40Z", "user": 1}, "model": "items.tweetitem", "pk": 3}, {"fields": {"deleted": false, "text": "Doing a coding test!", "created_at": "2016-04-07T20:27:37Z", "user": 1}, "model": "items.tweetitem", "pk": 4}, {"fields": {"action_flag": 1, "action_time": "2016-04-07T18:19:10.484Z", "object_repr": "TweetItem object", "object_id": "1", "change_message": "", "user": 1, "content_type": 9}, "model": "admin.logentry", "pk": 1}, {"fields": {"action_flag": 1, "action_time": "2016-04-07T18:21:35.148Z", "object_repr": "TweetItem object", "object_id": "2", "change_message": "", "user": 1, "content_type": 9}, "model": "admin.logentry", "pk": 2}, {"fields": {"action_flag": 1, "action_time": "2016-04-07T18:21:45.396Z", "object_repr": "TweetItem object", "object_id": "3", "change_message": "", "user": 1, "content_type": 9}, "model": "admin.logentry", "pk": 3}, {"fields": {"action_flag": 1, "action_time": "2016-04-07T18:28:43.284Z", "object_repr": "Stream object", "object_id": "3", "change_message": "", "user": 1, "content_type": 7}, "model": "admin.logentry", "pk": 4}, {"fields": {"action_flag": 2, "action_time": "2016-04-07T18:29:08.073Z", "object_repr": "Stream object", "object_id": "3", "change_message": "Changed tweet_item.", "user": 1, "content_type": 7}, "model": "admin.logentry", "pk": 5}, {"fields": {"action_flag": 1, "action_time": "2016-04-07T18:29:13.999Z", "object_repr": "Stream object", "object_id": "4", "change_message": "", "user": 1, "content_type": 7}, "model": "admin.logentry", "pk": 6}, {"fields": {"action_flag": 1, "action_time": "2016-04-07T18:31:23.371Z", "object_repr": "PhotoItem object", "object_id": "1", "change_message": "", "user": 1, "content_type": 8}, "model": "admin.logentry", "pk": 7}, {"fields": {"action_flag": 1, "action_time": "2016-04-07T18:31:25.486Z", "object_repr": "Stream object", "object_id": "5", "change_message": "", "user": 1, "content_type": 7}, "model": "admin.logentry", "pk": 8}, {"fields": {"action_flag": 3, "action_time": "2016-04-07T18:42:55.798Z", "object_repr": "PhotoItem object", "object_id": "1", "change_message": "", "user": 1, "content_type": 8}, "model": "admin.logentry", "pk": 9}, {"fields": {"action_flag": 1, "action_time": "2016-04-07T18:46:21.218Z", "object_repr": "PhotoItem object", "object_id": "2", "change_message": "", "user": 1, "content_type": 8}, "model": "admin.logentry", "pk": 10}, {"fields": {"action_flag": 1, "action_time": "2016-04-07T18:46:23.068Z", "object_repr": "Stream object", "object_id": "6", "change_message": "", "user": 1, "content_type": 7}, "model": "admin.logentry", "pk": 11}, {"fields": {"action_flag": 3, "action_time": "2016-04-07T18:46:37.489Z", "object_repr": "PhotoItem object", "object_id": "2", "change_message": "", "user": 1, "content_type": 8}, "model": "admin.logentry", "pk": 12}, {"fields": {"action_flag": 1, "action_time": "2016-04-07T18:50:28.284Z", "object_repr": "PhotoItem object", "object_id": "3", "change_message": "", "user": 1, "content_type": 8}, "model": "admin.logentry", "pk": 13}, {"fields": {"action_flag": 2, "action_time": "2016-04-07T18:50:39.943Z", "object_repr": "Stream object", "object_id": "6", "change_message": "Changed photo_item.", "user": 1, "content_type": 7}, "model": "admin.logentry", "pk": 14}, {"fields": {"action_flag": 2, "action_time": "2016-04-07T20:09:09.302Z", "object_repr": "PhotoItem object", "object_id": "3", "change_message": "Changed deleted.", "user": 1, "content_type": 8}, "model": "admin.logentry", "pk": 15}, {"fields": {"action_flag": 2, "action_time": "2016-04-07T20:09:14.830Z", "object_repr": "PhotoItem object", "object_id": "3", "change_message": "Changed deleted.", "user": 1, "content_type": 8}, "model": "admin.logentry", "pk": 16}, {"fields": {"action_flag": 2, "action_time": "2016-04-07T20:09:29.844Z", "object_repr": "TweetItem object", "object_id": "2", "change_message": "Changed deleted.", "user": 1, "content_type": 9}, "model": "admin.logentry", "pk": 17}, {"fields": {"action_flag": 2, "action_time": "2016-04-07T20:10:12.245Z", "object_repr": "TweetItem object", "object_id": "3", "change_message": "Changed deleted.", "user": 1, "content_type": 9}, "model": "admin.logentry", "pk": 18}, {"fields": {"action_flag": 2, "action_time": "2016-04-07T20:10:17.465Z", "object_repr": "TweetItem object", "object_id": "3", "change_message": "Changed deleted.", "user": 1, "content_type": 9}, "model": "admin.logentry", "pk": 19}, {"fields": {"action_flag": 2, "action_time": "2016-04-07T20:13:43.505Z", "object_repr": "PhotoItem object", "object_id": "3", "change_message": "Changed image.", "user": 1, "content_type": 8}, "model": "admin.logentry", "pk": 20}, {"fields": {"action_flag": 2, "action_time": "2016-04-07T20:14:24.245Z", "object_repr": "PhotoItem object", "object_id": "3", "change_message": "Changed deleted.", "user": 1, "content_type": 8}, "model": "admin.logentry", "pk": 21}, {"fields": {"action_flag": 2, "action_time": "2016-04-07T20:14:30.493Z", "object_repr": "PhotoItem object", "object_id": "3", "change_message": "Changed deleted.", "user": 1, "content_type": 8}, "model": "admin.logentry", "pk": 22}, {"fields": {"action_flag": 1, "action_time": "2016-04-07T20:27:46.869Z", "object_repr": "TweetItem object", "object_id": "4", "change_message": "", "user": 1, "content_type": 9}, "model": "admin.logentry", "pk": 23}, {"fields": {"action_flag": 1, "action_time": "2016-04-07T20:28:08.373Z", "object_repr": "Stream object", "object_id": "7", "change_message": "", "user": 1, "content_type": 7}, "model": "admin.logentry", "pk": 24}] \ No newline at end of file diff --git a/testsite/items/migrations/0002_auto_20160407_1850.py b/testsite/items/migrations/0002_auto_20160407_1850.py new file mode 100644 index 0000000..7da2d4d --- /dev/null +++ b/testsite/items/migrations/0002_auto_20160407_1850.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('items', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='photoitem', + name='deleted', + field=models.BooleanField(default=False), + preserve_default=True, + ), + migrations.AddField( + model_name='tweetitem', + name='deleted', + field=models.BooleanField(default=False), + preserve_default=True, + ), + ] diff --git a/testsite/items/models.py b/testsite/items/models.py index 7d7ebe0..f3ba129 100644 --- a/testsite/items/models.py +++ b/testsite/items/models.py @@ -5,6 +5,7 @@ class ItemAbstract(models.Model): user = models.ForeignKey(User) created_at = models.DateTimeField() + deleted = models.BooleanField(default=False) class Meta: abstract = True diff --git a/testsite/stream/migrations/0002_auto_20160407_1813.py b/testsite/stream/migrations/0002_auto_20160407_1813.py new file mode 100644 index 0000000..0ecfedc --- /dev/null +++ b/testsite/stream/migrations/0002_auto_20160407_1813.py @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('items', '0001_initial'), + ('stream', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='stream', + name='photo_item', + field=models.OneToOneField(default=None, to='items.PhotoItem'), + preserve_default=True, + ), + migrations.AddField( + model_name='stream', + name='tweet_item', + field=models.OneToOneField(default=None, to='items.TweetItem'), + preserve_default=True, + ), + ] diff --git a/testsite/stream/migrations/0003_auto_20160407_1820.py b/testsite/stream/migrations/0003_auto_20160407_1820.py new file mode 100644 index 0000000..6e68ea6 --- /dev/null +++ b/testsite/stream/migrations/0003_auto_20160407_1820.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('stream', '0002_auto_20160407_1813'), + ] + + operations = [ + migrations.AlterField( + model_name='stream', + name='photo_item', + field=models.ForeignKey(to='items.PhotoItem'), + preserve_default=True, + ), + migrations.AlterField( + model_name='stream', + name='tweet_item', + field=models.ForeignKey(to='items.TweetItem'), + preserve_default=True, + ), + ] diff --git a/testsite/stream/migrations/0004_auto_20160407_1828.py b/testsite/stream/migrations/0004_auto_20160407_1828.py new file mode 100644 index 0000000..64de52f --- /dev/null +++ b/testsite/stream/migrations/0004_auto_20160407_1828.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('stream', '0003_auto_20160407_1820'), + ] + + operations = [ + migrations.AlterField( + model_name='stream', + name='photo_item', + field=models.ForeignKey(blank=True, to='items.PhotoItem', null=True), + preserve_default=True, + ), + migrations.AlterField( + model_name='stream', + name='tweet_item', + field=models.ForeignKey(blank=True, to='items.TweetItem', null=True), + preserve_default=True, + ), + ] diff --git a/testsite/stream/migrations/0005_auto_20160407_1850.py b/testsite/stream/migrations/0005_auto_20160407_1850.py new file mode 100644 index 0000000..0725299 --- /dev/null +++ b/testsite/stream/migrations/0005_auto_20160407_1850.py @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('stream', '0004_auto_20160407_1828'), + ] + + operations = [ + migrations.AlterField( + model_name='stream', + name='photo_item', + field=models.ForeignKey(on_delete=django.db.models.deletion.SET_NULL, blank=True, to='items.PhotoItem', null=True), + preserve_default=True, + ), + migrations.AlterField( + model_name='stream', + name='tweet_item', + field=models.ForeignKey(on_delete=django.db.models.deletion.SET_NULL, blank=True, to='items.TweetItem', null=True), + preserve_default=True, + ), + ] diff --git a/testsite/stream/models.py b/testsite/stream/models.py index e10fd24..8a7983d 100644 --- a/testsite/stream/models.py +++ b/testsite/stream/models.py @@ -1,7 +1,15 @@ from django.db import models from django.contrib.auth.models import User - +from items.models import PhotoItem, TweetItem class Stream(models.Model): user = models.ForeignKey(User) - created_at = models.DateTimeField() \ No newline at end of file + created_at = models.DateTimeField() + photo_item = models.ForeignKey(PhotoItem, + on_delete=models.SET_NULL, + blank=True, + null=True) + tweet_item = models.ForeignKey(TweetItem, + on_delete=models.SET_NULL, + blank=True, + null=True) diff --git a/testsite/stream/templates/stream.html b/testsite/stream/templates/stream.html new file mode 100644 index 0000000..1a7a179 --- /dev/null +++ b/testsite/stream/templates/stream.html @@ -0,0 +1,18 @@ +

Stream Data

+ + diff --git a/testsite/stream/views.py b/testsite/stream/views.py index 91ea44a..a30490f 100644 --- a/testsite/stream/views.py +++ b/testsite/stream/views.py @@ -1,3 +1,30 @@ -from django.shortcuts import render +from django.shortcuts import get_list_or_404, render +from stream.models import Stream +from django.conf import settings # Create your views here. +def show_stream(request): + stream_list = get_list_or_404(Stream.objects.order_by('created_at')) + current_stream = [] # Items that are not deleted + + print 'stream_data', stream_list + + for stream in stream_list: + + # handle tweets + if(stream.tweet_item != None and stream.tweet_item.deleted == False): + current_stream.append({ + 'type': 'tweet', + 'text': stream.tweet_item.text, + 'time': str(stream.created_at)}) + + # handle photos + elif(stream.photo_item != None and stream.photo_item.deleted == False): + current_stream.append({ + 'type': 'photo', + 'img_href': stream.photo_item.image.url, + 'time': str(stream.created_at)}) + + # render HTML from template + obj = render(request, './stream.html', {'stream_data': current_stream}) + return obj diff --git a/testsite/testsite/settings.py b/testsite/testsite/settings.py index 2821860..1bc60a1 100644 --- a/testsite/testsite/settings.py +++ b/testsite/testsite/settings.py @@ -22,6 +22,8 @@ # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True +MEDIA_URL = '/images/' + TEMPLATE_DEBUG = True ALLOWED_HOSTS = [] diff --git a/testsite/testsite/urls.py b/testsite/testsite/urls.py index bcd73c7..d07213c 100644 --- a/testsite/testsite/urls.py +++ b/testsite/testsite/urls.py @@ -1,5 +1,7 @@ from django.conf.urls import patterns, include, url from django.contrib import admin +from django.conf import settings +from django.conf.urls.static import static urlpatterns = patterns('', # Examples: @@ -7,4 +9,6 @@ # url(r'^blog/', include('blog.urls')), url(r'^admin/', include(admin.site.urls)), -) + url(r'^stream/', 'stream.views.show_stream'), + +) + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)