diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..67e78e9
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,41 @@
+# Numerous always-ignore extensions
+*.pyc
+*.diff
+*.err
+*.orig
+*.log
+*.rej
+*.swo
+*.swp
+*.vi
+*.cache
+*.egg-info
+*~
+*#
+
+# OS or Editor folders
+.DS_Store
+Thumbs.db
+.cache
+.project
+.settings
+.tmproj
+*.esproj
+nbproject
+*.sublime-project
+*.sublime-workspace
+.tm_properties
+._*
+
+# Folders to ignore
+.hg
+.svn
+.CVS
+.idea
+_assets
+_design
+_content
+_tmp
+dist
+build
+_build
diff --git a/mysite/__init__.pyc b/mysite/__init__.pyc
deleted file mode 100644
index 30808d0..0000000
Binary files a/mysite/__init__.pyc and /dev/null differ
diff --git a/mysite/settings.py b/mysite/settings.py
index 8e12620..121685b 100644
--- a/mysite/settings.py
+++ b/mysite/settings.py
@@ -103,11 +103,15 @@
# Python dotted path to the WSGI application used by Django's runserver.
WSGI_APPLICATION = 'mysite.wsgi.application'
+import os.path
+BASE_PATH = os.path.normpath(os.path.dirname(__file__))
+
TEMPLATE_DIRS = (
# Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
# Always use forward slashes, even on Windows.
- # Don't forget to use absolute paths, not relative paths.
-)
+ # Don't forget to use absolute paths, not relative paths.
+ BASE_PATH + "/templates/",
+ )
INSTALLED_APPS = (
'django.contrib.auth',
@@ -117,7 +121,7 @@
'django.contrib.messages',
'django.contrib.staticfiles',
# Uncomment the next line to enable the admin:
- # 'django.contrib.admin',
+ 'django.contrib.admin',
# Uncomment the next line to enable admin documentation:
# 'django.contrib.admindocs',
'polls',
diff --git a/mysite/settings.pyc b/mysite/settings.pyc
deleted file mode 100644
index 54c54fe..0000000
Binary files a/mysite/settings.pyc and /dev/null differ
diff --git a/mysite/templates/admin/base_site.html b/mysite/templates/admin/base_site.html
new file mode 100644
index 0000000..0717edf
--- /dev/null
+++ b/mysite/templates/admin/base_site.html
@@ -0,0 +1,10 @@
+{% extends "admin/base.html" %}
+{% load i18n %}
+
+{% block title %}MySite Corp Global Industries {{ title }} | {% trans 'Django site admin' %}e{% endblock %}
+
+{% block branding %}
+
MySite Corp Global Industries {% trans 'Django administration' %}
+{% endblock %}
+
+{% block nav-global %}{% endblock %}
diff --git a/mysite/urls.py b/mysite/urls.py
index ebbc31d..b884696 100644
--- a/mysite/urls.py
+++ b/mysite/urls.py
@@ -1,17 +1,9 @@
from django.conf.urls import patterns, include, url
-# Uncomment the next two lines to enable the admin:
-# from django.contrib import admin
-# admin.autodiscover()
+from django.contrib import admin
+admin.autodiscover()
urlpatterns = patterns('',
- # Examples:
- # url(r'^$', 'mysite.views.home', name='home'),
- # url(r'^mysite/', include('mysite.foo.urls')),
-
- # Uncomment the admin/doc line below to enable admin documentation:
- # url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
-
- # Uncomment the next line to enable the admin:
- # url(r'^admin/', include(admin.site.urls)),
+ url(r'^polls/', include('polls.urls', namespace="polls")),
+ url(r'^admin/', include(admin.site.urls)),
)
diff --git a/mysite/urls.pyc b/mysite/urls.pyc
deleted file mode 100644
index 916e176..0000000
Binary files a/mysite/urls.pyc and /dev/null differ
diff --git a/mysite/wsgi.pyc b/mysite/wsgi.pyc
deleted file mode 100644
index a005e01..0000000
Binary files a/mysite/wsgi.pyc and /dev/null differ
diff --git a/polls/__init__.pyc b/polls/__init__.pyc
deleted file mode 100644
index 20c9239..0000000
Binary files a/polls/__init__.pyc and /dev/null differ
diff --git a/polls/admin.py b/polls/admin.py
new file mode 100644
index 0000000..e144212
--- /dev/null
+++ b/polls/admin.py
@@ -0,0 +1,23 @@
+from django.contrib import admin
+from polls.models import Poll
+from polls.models import Choice
+
+class ChoiceInline(admin.TabularInline):
+ model = Choice
+ extra = 3
+
+
+class PollAdmin(admin.ModelAdmin):
+ fieldsets = [
+ (None, {'fields': ['question']}),
+ ('Date information', {'fields': ['pub_date'], 'classes': ['collapse']}),
+ ]
+ list_display = ('question', 'pub_date', 'was_published_recently')
+ list_filter = ['pub_date']
+ search_fields = ['question']
+ date_hierarchy = 'pub_date'
+ inlines = [ChoiceInline]
+
+admin.site.register(Poll, PollAdmin)
+
+
diff --git a/polls/models.py b/polls/models.py
index f8cc376..d1fdd01 100644
--- a/polls/models.py
+++ b/polls/models.py
@@ -10,7 +10,11 @@ def __unicode__(self):
return self.question
def was_published_recently(self):
- return self.pub_date >= timezone.now() - datetime.timedelta(days=1)
+ now = timezone.now()
+ return now > self.pub_date >= now - datetime.timedelta(days=1)
+ was_published_recently.admin_order_field = 'pub_date'
+ was_published_recently.boolean = True
+ was_published_recently.short_description = 'Published recently?'
class Choice(models.Model):
diff --git a/polls/models.pyc b/polls/models.pyc
deleted file mode 100644
index af237db..0000000
Binary files a/polls/models.pyc and /dev/null differ
diff --git a/polls/templates/polls/detail.html b/polls/templates/polls/detail.html
new file mode 100644
index 0000000..15da227
--- /dev/null
+++ b/polls/templates/polls/detail.html
@@ -0,0 +1,12 @@
+{{ poll.question }}
+
+{% if error_message %}{{ error_message }}
{% endif %}
+
+
diff --git a/polls/templates/polls/index.html b/polls/templates/polls/index.html
new file mode 100644
index 0000000..4c15ce4
--- /dev/null
+++ b/polls/templates/polls/index.html
@@ -0,0 +1,9 @@
+{% if latest_poll_list %}
+
+{% else %}
+ No polls are available.
+{% endif %}
diff --git a/polls/templates/polls/results.html b/polls/templates/polls/results.html
new file mode 100644
index 0000000..d6783ba
--- /dev/null
+++ b/polls/templates/polls/results.html
@@ -0,0 +1,9 @@
+{{ poll.question }}
+
+
+{% for choice in poll.choice_set.all %}
+ - {{ choice.choice_text }} -- {{ choice.votes }} vote{{ choice.votes|pluralize }}
+{% endfor %}
+
+
+Vote again?
diff --git a/polls/tests.py b/polls/tests.py
index 501deb7..2baf66e 100644
--- a/polls/tests.py
+++ b/polls/tests.py
@@ -1,16 +1,32 @@
-"""
-This file demonstrates writing tests using the unittest module. These will pass
-when you run "manage.py test".
-
-Replace this with more appropriate tests for your application.
-"""
+import datetime
+from django.utils import timezone
from django.test import TestCase
+from polls.models import Poll
+
+class PollMethodTests(TestCase):
+
+ def test_was_published_recently_with_future_poll(self):
+ """
+ was_published_recently() should return False for polls whose
+ pub_date is in the future
+ """
+ future_poll = Poll(pub_date=timezone.now() + datetime.timedelta(days=30))
+ self.assertEqual(future_poll.was_published_recently(), False)
+
+ def test_was_published_recently_with_old_poll(self):
+ """
+ was_published_recently() should return False for polls whose pub_date
+ is older than 1 day
+ """
+ old_poll = Poll(pub_date=timezone.now() - datetime.timedelta(days=30))
+ self.assertEqual(old_poll.was_published_recently(), False)
-class SimpleTest(TestCase):
- def test_basic_addition(self):
+ def test_was_published_recently_with_recent_poll(self):
"""
- Tests that 1 + 1 always equals 2.
+ was_published_recently() should return True for polls whose pub_date
+ is within the last day
"""
- self.assertEqual(1 + 1, 2)
+ recent_poll = Poll(pub_date=timezone.now() - datetime.timedelta(hours=1))
+ self.assertEqual(recent_poll.was_published_recently(), True)
diff --git a/polls/testsettings.py b/polls/testsettings.py
new file mode 100644
index 0000000..b52b3f0
--- /dev/null
+++ b/polls/testsettings.py
@@ -0,0 +1,13 @@
+DATABASES = {
+ 'default': {
+ 'ENGINE': 'django.db.backends.sqlite3',
+ 'NAME': 'pollstests.db',
+ # The following settings are not used with sqlite3:
+ 'USER': '',
+ 'PASSWORD': '',
+ 'HOST': '',
+ 'PORT': '',
+ }
+}
+
+SECRET_KEY = 'i4mth3m0sts3cr3t0f4lls3tti1ngs'
diff --git a/polls/urls.py b/polls/urls.py
new file mode 100644
index 0000000..3127d0b
--- /dev/null
+++ b/polls/urls.py
@@ -0,0 +1,23 @@
+from django.conf.urls import patterns, url
+from django.views.generic import DetailView, ListView
+from polls.models import Poll
+
+urlpatterns = patterns('',
+ url(r'^$',
+ ListView.as_view(
+ queryset=Poll.objects.order_by('-pub_date')[:5],
+ context_object_name='latest_poll_list',
+ template_name='polls/index.html'),
+ name='index'),
+ url(r'^(?P\d+)/$',
+ DetailView.as_view(
+ model=Poll,
+ template_name='polls/detail.html'),
+ name='detail'),
+ url(r'^(?P\d+)/results/$',
+ DetailView.as_view(
+ model=Poll,
+ template_name='polls/results.html'),
+ name='results'),
+ url(r'^(?P\d+)/vote/$', 'polls.views.vote', name='vote'),
+)
diff --git a/polls/views.py b/polls/views.py
index 60f00ef..bb42fc0 100644
--- a/polls/views.py
+++ b/polls/views.py
@@ -1 +1,27 @@
-# Create your views here.
+from django.shortcuts import get_object_or_404, render
+from django.http import HttpResponseRedirect
+from django.core.urlresolvers import reverse
+from polls.models import Choice, Poll
+
+def vote(request, poll_id):
+ p = get_object_or_404(Poll, pk=poll_id)
+ try:
+ selected_choice = p.choice_set.get(pk=request.POST['choice'])
+ except (KeyError, Choice.DoesNotExist):
+ # Redisplay the poll voting form.
+ return render(request, 'polls/detail.html', {
+ 'poll': p,
+ 'error_message': "You didn't select a choice.",
+ })
+ else:
+ selected_choice.votes += 1
+ selected_choice.save()
+ # Always return an HttpResponseRedirect after successfully dealing
+ # with POST data. This prevents data from being posted twice if a
+ # user hits the Back button.
+ return HttpResponseRedirect(reverse('polls:results', args=(p.id,)))
+
+
+def results(request, poll_id):
+ poll = get_object_or_404(Poll, pk=poll_id)
+ return render(request, 'polls/results.html', {'poll': poll})