diff --git a/fabfile.py b/fabfile.py index 18a53bb..756846c 100644 --- a/fabfile.py +++ b/fabfile.py @@ -14,5 +14,10 @@ def migrate(): def make_migrations(): run_manage('makemigrations') +def load_sample_data(): + run_manage('flush') + run_manage('loaddata auth_data') + run_manage('loaddata sample_data') + def requirements(): local('/home/vagrant/.virtualenvs/le-code-test/bin/pip install -r requirements.txt ') \ No newline at end of file diff --git a/testsite/items/fixtures/sample_data.json b/testsite/items/fixtures/sample_data.json new file mode 100644 index 0000000..93f6889 --- /dev/null +++ b/testsite/items/fixtures/sample_data.json @@ -0,0 +1,47 @@ +[ +{ + "fields": { + "created_at": "2015-10-05T12:21:06Z", + "user": 1, + "image": "/media/python-logo-master-v3-TM-flattened.png" + }, + "model": "items.photoitem", + "pk": 1 +}, +{ + "fields": { + "created_at": "2015-10-03T13:06:14Z", + "user": 1, + "image": "/media/python-logo-master-v3-TM-flattened.png" + }, + "model": "items.photoitem", + "pk": 2 +}, +{ + "fields": { + "text": "Had corn flakes for breakfast", + "created_at": "2015-10-02T08:10:10Z", + "user": 1 + }, + "model": "items.tweetitem", + "pk": 1 +}, +{ + "fields": { + "text": "Had salmon for lunch today", + "created_at": "2015-10-04T12:54:43Z", + "user": 1 + }, + "model": "items.tweetitem", + "pk": 2 +}, +{ + "fields": { + "text": "Had a roast beef dinner", + "created_at": "2015-10-04T18:41:47Z", + "user": 1 + }, + "model": "items.tweetitem", + "pk": 3 +} +] diff --git a/testsite/media/python-logo-master-v3-TM-flattened.png b/testsite/media/python-logo-master-v3-TM-flattened.png new file mode 100644 index 0000000..738f6ed Binary files /dev/null and b/testsite/media/python-logo-master-v3-TM-flattened.png differ diff --git a/testsite/stream/migrations/0002_auto_20151005_1926.py b/testsite/stream/migrations/0002_auto_20151005_1926.py new file mode 100644 index 0000000..d598f0a --- /dev/null +++ b/testsite/stream/migrations/0002_auto_20151005_1926.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('contenttypes', '0001_initial'), + ('stream', '0001_initial'), + ] + + operations = [ + migrations.AlterModelOptions( + name='stream', + options={'ordering': ['-created_at']}, + ), + migrations.AddField( + model_name='stream', + name='content_type', + field=models.ForeignKey(default=36, to='contenttypes.ContentType'), + preserve_default=False, + ), + migrations.AddField( + model_name='stream', + name='object_id', + field=models.PositiveIntegerField(default=1), + preserve_default=False, + ), + ] diff --git a/testsite/stream/migrations/0003_stream_deleted.py b/testsite/stream/migrations/0003_stream_deleted.py new file mode 100644 index 0000000..bc449e8 --- /dev/null +++ b/testsite/stream/migrations/0003_stream_deleted.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('stream', '0002_auto_20151005_1926'), + ] + + operations = [ + migrations.AddField( + model_name='stream', + name='deleted', + field=models.BooleanField(default=False), + preserve_default=True, + ), + ] diff --git a/testsite/stream/models.py b/testsite/stream/models.py index e10fd24..082d7bd 100644 --- a/testsite/stream/models.py +++ b/testsite/stream/models.py @@ -1,7 +1,46 @@ from django.db import models from django.contrib.auth.models import User +from django.contrib.contenttypes.fields import GenericForeignKey +from django.contrib.contenttypes.models import ContentType +from django.db.models import signals + +from items.models import PhotoItem, TweetItem + + +class NotDeletedStreamManager(models.Manager): + def get_queryset(self): + return super(NotDeletedStreamManager, self).get_queryset().filter(deleted=False) class Stream(models.Model): user = models.ForeignKey(User) - created_at = models.DateTimeField() \ No newline at end of file + created_at = models.DateTimeField() + + content_type = models.ForeignKey(ContentType) + object_id = models.PositiveIntegerField() + content_object = GenericForeignKey() + + deleted = models.BooleanField(default=False) + + class Meta: + ordering = ['-created_at'] + + objects = models.Manager() + active = NotDeletedStreamManager() + + def __unicode__(self): + return '{} {}: {}'.format(self.__class__.__name__, + self.content_type.model, + self.created_at) + + +def update_stream(sender, instance, created, **kwargs): + if created: + Stream.objects.create( + user=instance.user, + created_at=instance.created_at, + content_type=ContentType.objects.get_for_model(sender), + object_id=instance.id) + +for item_type in (TweetItem, PhotoItem): + signals.post_save.connect(update_stream, sender=item_type) \ No newline at end of file diff --git a/testsite/stream/views.py b/testsite/stream/views.py index 91ea44a..664421c 100644 --- a/testsite/stream/views.py +++ b/testsite/stream/views.py @@ -1,3 +1,7 @@ from django.shortcuts import render -# Create your views here. +from models import Stream + +def stream(request): + return render(request, 'stream.html', + {'stream': Stream.active.all()}) diff --git a/testsite/testsite/fixtures/auth_data.json b/testsite/testsite/fixtures/auth_data.json new file mode 100644 index 0000000..7b2d40f --- /dev/null +++ b/testsite/testsite/fixtures/auth_data.json @@ -0,0 +1,263 @@ +[ +{ + "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": "2015-10-05T18:54:02.247Z", + "groups": [], + "user_permissions": [], + "password": "pbkdf2_sha256$12000$1THWo6CjRL0S$OKr+1Fil+oUQZ8c3LWZm+FEX69V3bzHRenCI9XApyqY=", + "email": "", + "date_joined": "2015-10-05T18:54:02.247Z" + }, + "model": "auth.user", + "pk": 1 +} +] diff --git a/testsite/testsite/settings.py b/testsite/testsite/settings.py index 2821860..31cfe7b 100644 --- a/testsite/testsite/settings.py +++ b/testsite/testsite/settings.py @@ -66,6 +66,14 @@ } } +TEMPLATE_DIRS = ( + os.path.join(BASE_DIR, 'testsite', 'templates'), +) + +FIXTURE_DIRS = ( + os.path.join(os.path.dirname(__file__), 'fixtures'), +) + # Internationalization # https://docs.djangoproject.com/en/1.7/topics/i18n/ @@ -84,3 +92,7 @@ # https://docs.djangoproject.com/en/1.7/howto/static-files/ STATIC_URL = '/static/' + +MEDIA_URL = '/media/' + +MEDIA_ROOT = os.path.join(BASE_DIR, 'media') diff --git a/testsite/testsite/templates/stream.html b/testsite/testsite/templates/stream.html new file mode 100644 index 0000000..d4b3073 --- /dev/null +++ b/testsite/testsite/templates/stream.html @@ -0,0 +1,28 @@ + + + + Stream Page + + + + +
+ {% for item in stream %} +
+
+
+ {% if item.content_type.model == 'photoitem' %} + + {% elif item.content_type.model == 'tweetitem' %} +

{{ item.content_object.text }}

+ {% endif %} +
    +
  • {{ item.created_at }}
  • +
+
+
+
+ {% endfor %} +
+ + \ No newline at end of file diff --git a/testsite/testsite/urls.py b/testsite/testsite/urls.py index bcd73c7..b93c51a 100644 --- a/testsite/testsite/urls.py +++ b/testsite/testsite/urls.py @@ -1,10 +1,15 @@ -from django.conf.urls import patterns, include, url +from django.conf.urls import include, url from django.contrib import admin +from django.conf import settings +from django.conf.urls.static import static -urlpatterns = patterns('', +from stream import views + +urlpatterns = [ # Examples: # url(r'^$', 'testsite.views.home', name='home'), # url(r'^blog/', include('blog.urls')), url(r'^admin/', include(admin.site.urls)), -) + url(r'^stream/', views.stream) +] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)