Merge lp:~nataliabidart/locolander/project-forms into lp:locolander

Proposed by Natalia Bidart
Status: Merged
Approved by: Natalia Bidart
Approved revision: 9
Merged at revision: 4
Proposed branch: lp:~nataliabidart/locolander/project-forms
Merge into: lp:locolander
Diff against target: 314 lines (+199/-10)
15 files modified
locolander/locolander/settings.py (+1/-1)
locolander/locolander/urls.py (+4/-6)
locolander/locolanderweb/forms.py (+21/-0)
locolander/locolanderweb/models.py (+1/-0)
locolander/locolanderweb/templates/base.html (+19/-0)
locolander/locolanderweb/templates/locolanderweb/home.html (+8/-0)
locolander/locolanderweb/templates/locolanderweb/project/_list.html (+17/-0)
locolander/locolanderweb/templates/locolanderweb/project/add.html (+21/-0)
locolander/locolanderweb/templates/locolanderweb/project/list.html (+5/-0)
locolander/locolanderweb/tests/__init__.py (+3/-1)
locolander/locolanderweb/tests/test_forms.py (+19/-0)
locolander/locolanderweb/tests/test_models.py (+1/-1)
locolander/locolanderweb/tests/test_views.py (+31/-0)
locolander/locolanderweb/urls.py (+9/-0)
locolander/locolanderweb/views.py (+39/-1)
To merge this branch: bzr merge lp:~nataliabidart/locolander/project-forms
Reviewer Review Type Date Requested Status
Loco Lander Approve
Review via email: mp+170865@code.launchpad.net

Commit message

- Added forms, templates and minimal logic for project list/adding.

To post a comment you must log in.
6. By Natalia Bidart

Added new line.

7. By Natalia Bidart

Merged moar-models into project-forms.

Revision history for this message
Ricardo Kirkner (ricardokirkner) wrote :

l. 73: we should be using south from the beginning to manage schema migrations
l. 111: why not define this in the view instead of the template?
l. 127: missing {{ }} around p.url

Revision history for this message
Natalia Bidart (nataliabidart) wrote :

> l. 73: we should be using south from the beginning to manage schema migrations

Yes, will add in another branch.

> l. 111: why not define this in the view instead of the template?

Is a preliminary version, I'm not sure we want to show this in the home page.

> l. 127: missing {{ }} around p.url

Added!

Thanks

8. By Natalia Bidart

Fixes.

9. By Natalia Bidart

Fixes as per review.

Revision history for this message
Loco Lander (locolander) wrote :

LGTM

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'locolander/locolander/settings.py'
2--- locolander/locolander/settings.py 2013-06-20 22:59:33 +0000
3+++ locolander/locolander/settings.py 2013-06-21 20:36:27 +0000
4@@ -121,7 +121,7 @@
5 'django.contrib.messages',
6 'django.contrib.staticfiles',
7 # Uncomment the next line to enable the admin:
8- # 'django.contrib.admin',
9+ 'django.contrib.admin',
10 # Uncomment the next line to enable admin documentation:
11 # 'django.contrib.admindocs',
12 'locolanderweb',
13
14=== modified file 'locolander/locolander/urls.py'
15--- locolander/locolander/urls.py 2013-06-20 22:13:51 +0000
16+++ locolander/locolander/urls.py 2013-06-21 20:36:27 +0000
17@@ -1,17 +1,15 @@
18 from django.conf.urls import patterns, include, url
19+from django.contrib import admin
20+admin.autodiscover()
21
22-# Uncomment the next two lines to enable the admin:
23-# from django.contrib import admin
24-# admin.autodiscover()
25
26 urlpatterns = patterns('',
27 # Examples:
28- # url(r'^$', 'locolander.views.home', name='home'),
29- # url(r'^locolander/', include('locolander.foo.urls')),
30+ url(r'', include('locolanderweb.urls')),
31
32 # Uncomment the admin/doc line below to enable admin documentation:
33 # url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
34
35 # Uncomment the next line to enable the admin:
36- # url(r'^admin/', include(admin.site.urls)),
37+ url(r'^admin/', include(admin.site.urls)),
38 )
39
40=== added file 'locolander/locolanderweb/forms.py'
41--- locolander/locolanderweb/forms.py 1970-01-01 00:00:00 +0000
42+++ locolander/locolanderweb/forms.py 2013-06-21 20:36:27 +0000
43@@ -0,0 +1,21 @@
44+from django import forms
45+
46+from locolanderweb.models import Project
47+
48+
49+class ProjectForm(forms.ModelForm):
50+
51+ def __init__(self, owner, **kwargs):
52+ self.owner = owner
53+ super(ProjectForm, self).__init__(**kwargs)
54+
55+ def save(self, *args, **kwargs):
56+ self.instance.owner = self.owner
57+ return super(ProjectForm, self).save(*args, **kwargs)
58+
59+ class Meta:
60+ model = Project
61+ exclude = ('owner',)
62+ widgets = {
63+ 'name': forms.TextInput(),
64+ }
65
66=== modified file 'locolander/locolanderweb/models.py'
67--- locolander/locolanderweb/models.py 2013-06-20 23:28:02 +0000
68+++ locolander/locolanderweb/models.py 2013-06-21 20:36:27 +0000
69@@ -15,3 +15,4 @@
70
71 project = models.ForeignKey(Project)
72 timestamp = models.DateTimeField(default=datetime.utcnow)
73+ raw = models.TextField()
74
75=== added directory 'locolander/locolanderweb/static'
76=== added directory 'locolander/locolanderweb/templates'
77=== added file 'locolander/locolanderweb/templates/base.html'
78--- locolander/locolanderweb/templates/base.html 1970-01-01 00:00:00 +0000
79+++ locolander/locolanderweb/templates/base.html 2013-06-21 20:36:27 +0000
80@@ -0,0 +1,19 @@
81+<html>
82+ <head>
83+ <title>{% block html-title %}Loco Lander{% endblock html-title %}</title>
84+ {% block head-extra %}{% endblock head-extra %}
85+ </head>
86+
87+ <body>
88+
89+ <div id="content">
90+ {% block content %}{% endblock content %}
91+ </div>
92+
93+ <div id="footer">
94+ {% block footer %}{% endblock footer %}
95+ </div>
96+
97+ </body>
98+
99+</html>
100
101=== added directory 'locolander/locolanderweb/templates/locolanderweb'
102=== added file 'locolander/locolanderweb/templates/locolanderweb/home.html'
103--- locolander/locolanderweb/templates/locolanderweb/home.html 1970-01-01 00:00:00 +0000
104+++ locolander/locolanderweb/templates/locolanderweb/home.html 2013-06-21 20:36:27 +0000
105@@ -0,0 +1,8 @@
106+{% extends "base.html" %}
107+
108+{% block content %}
109+<h1>Welcome!</h1>
110+
111+{% include "locolanderweb/project/_list.html" %}
112+
113+{% endblock content %}
114
115=== added directory 'locolander/locolanderweb/templates/locolanderweb/project'
116=== added file 'locolander/locolanderweb/templates/locolanderweb/project/_list.html'
117--- locolander/locolanderweb/templates/locolanderweb/project/_list.html 1970-01-01 00:00:00 +0000
118+++ locolander/locolanderweb/templates/locolanderweb/project/_list.html 2013-06-21 20:36:27 +0000
119@@ -0,0 +1,17 @@
120+<div id="projects">
121+{% if projects %}
122+ <h3>Your projects:</h3>
123+ <table>
124+ {% for p in projects %}
125+ <tr>
126+ <th>{{ p.name }}</th>
127+ <td>{{ p.url }}</td>
128+ </tr>
129+ {% endfor %}
130+ </table>
131+{% else %}
132+ <h3>No projects.</h3>
133+{% endif %}
134+
135+<a href="{% url 'project-add' %}">Add a new project</a>
136+</div>
137
138=== added file 'locolander/locolanderweb/templates/locolanderweb/project/add.html'
139--- locolander/locolanderweb/templates/locolanderweb/project/add.html 1970-01-01 00:00:00 +0000
140+++ locolander/locolanderweb/templates/locolanderweb/project/add.html 2013-06-21 20:36:27 +0000
141@@ -0,0 +1,21 @@
142+{% extends "base.html" %}
143+
144+{% block content %}
145+<h1>Add a new project</h1>
146+
147+<div id="project-create">
148+
149+<form action="." method="POST">
150+ <table>
151+ {{ form.as_table }}
152+ <tr>
153+ <td />
154+ <td class="text-left">
155+ <input type="submit" name="create" value="Add" />
156+ </td>
157+ </table>
158+</form>
159+
160+</div>
161+
162+{% endblock content %}
163
164=== added file 'locolander/locolanderweb/templates/locolanderweb/project/list.html'
165--- locolander/locolanderweb/templates/locolanderweb/project/list.html 1970-01-01 00:00:00 +0000
166+++ locolander/locolanderweb/templates/locolanderweb/project/list.html 2013-06-21 20:36:27 +0000
167@@ -0,0 +1,5 @@
168+{% extends "base.html" %}
169+
170+{% block content %}
171+{% include "locolanderweb/project/_list.html" %}
172+{% endblock content %}
173
174=== modified file 'locolander/locolanderweb/tests/__init__.py'
175--- locolander/locolanderweb/tests/__init__.py 2013-06-20 22:59:33 +0000
176+++ locolander/locolanderweb/tests/__init__.py 2013-06-21 20:36:27 +0000
177@@ -1,2 +1,4 @@
178+from locolanderweb.tests.test_code_style import *
179+from locolanderweb.tests.test_forms import *
180 from locolanderweb.tests.test_models import *
181-from locolanderweb.tests.test_code_style import *
182+from locolanderweb.tests.test_views import *
183
184=== added file 'locolander/locolanderweb/tests/test_forms.py'
185--- locolander/locolanderweb/tests/test_forms.py 1970-01-01 00:00:00 +0000
186+++ locolander/locolanderweb/tests/test_forms.py 2013-06-21 20:36:27 +0000
187@@ -0,0 +1,19 @@
188+from locolanderweb.forms import ProjectForm
189+from locolanderweb.tests.test_models import BaseTestCase
190+
191+
192+class ProjectFormTestCase(BaseTestCase):
193+
194+ def setUp(self):
195+ super(ProjectFormTestCase, self).setUp()
196+ self.user = self.factory.make_user()
197+ self.data = dict(name='foo', url='http://foo.com/')
198+
199+ def test_model(self):
200+ self.obj = ProjectForm(owner=self.user, data=self.data)
201+ self.assertTrue(self.obj.is_valid(), 'errors: %s' % self.obj.errors)
202+
203+ instance = self.obj.save()
204+ self.assertEqual(instance.owner, self.user)
205+ for k, v in self.data.iteritems():
206+ self.assertEqual(getattr(instance, k), v)
207
208=== modified file 'locolander/locolanderweb/tests/test_models.py'
209--- locolander/locolanderweb/tests/test_models.py 2013-06-20 23:28:02 +0000
210+++ locolander/locolanderweb/tests/test_models.py 2013-06-21 20:36:27 +0000
211@@ -26,7 +26,7 @@
212 username = self.make_random_string(prefix='user')
213 if email is None:
214 email = '%s@example.com' % username
215- return User.objects.create(
216+ return User.objects.create_user(
217 username=username, password=password, email=email)
218
219 def make_project(self, user=None, url=None):
220
221=== added file 'locolander/locolanderweb/tests/test_views.py'
222--- locolander/locolanderweb/tests/test_views.py 1970-01-01 00:00:00 +0000
223+++ locolander/locolanderweb/tests/test_views.py 2013-06-21 20:36:27 +0000
224@@ -0,0 +1,31 @@
225+from django.core.urlresolvers import reverse
226+
227+from locolanderweb.forms import ProjectForm
228+from locolanderweb.tests.test_models import BaseTestCase
229+
230+
231+class ProjectAddTestCase(BaseTestCase):
232+
233+ password = '1234'
234+ url = reverse('project-add')
235+
236+ def setUp(self):
237+ super(ProjectAddTestCase, self).setUp()
238+ self.user = self.factory.make_user(password=self.password)
239+ assert self.client.login(username=self.user.username,
240+ password=self.password)
241+ self.data = dict(name='foo', url='http://foo.com/')
242+
243+ def test_get(self):
244+ assert self.user.project_set.all().count() == 0
245+ response = self.client.get(self.url)
246+
247+ self.assertContains(response, ProjectForm(owner=self.user).as_table())
248+ self.assertEqual(self.user.project_set.all().count(), 0)
249+
250+ def test_post(self):
251+ assert self.user.project_set.all().count() == 0
252+ response = self.client.post(self.url, data=self.data, follow=True)
253+
254+ messages = [m.message for m in response.context['messages']]
255+ self.assertIn('Project foo added.', messages)
256
257=== added file 'locolander/locolanderweb/urls.py'
258--- locolander/locolanderweb/urls.py 1970-01-01 00:00:00 +0000
259+++ locolander/locolanderweb/urls.py 2013-06-21 20:36:27 +0000
260@@ -0,0 +1,9 @@
261+from django.conf.urls import patterns, include, url
262+
263+
264+urlpatterns = patterns(
265+ 'locolanderweb.views',
266+ url(r'^$', 'home', name='home'),
267+ url(r'^projects/$', 'project_list', name='project-list'),
268+ url(r'^projects/add/$', 'project_add', name='project-add'),
269+)
270
271=== modified file 'locolander/locolanderweb/views.py'
272--- locolander/locolanderweb/views.py 2013-06-20 22:13:51 +0000
273+++ locolander/locolanderweb/views.py 2013-06-21 20:36:27 +0000
274@@ -1,1 +1,39 @@
275-# Create your views here.
276+from django.contrib import messages
277+from django.contrib.auth.decorators import login_required
278+from django.core.urlresolvers import reverse
279+from django.http import HttpResponseRedirect
280+from django.template.response import TemplateResponse
281+
282+from locolanderweb.forms import ProjectForm
283+
284+
285+@login_required
286+def home(request):
287+ context = dict(projects=request.user.project_set.all())
288+ return TemplateResponse(
289+ request, 'locolanderweb/home.html', context=context)
290+
291+
292+@login_required
293+def project_list(request):
294+ projects = request.user.project_set.all()
295+ return TemplateResponse(
296+ request, 'locolanderweb/project/list.html',
297+ context=dict(projects=projects))
298+
299+
300+@login_required
301+def project_add(request):
302+ if request.method == 'POST':
303+ form = ProjectForm(owner=request.user, data=request.POST)
304+ if form.is_valid():
305+ project = form.save()
306+ messages.success(request, 'Project %s added.' % project.name)
307+ return HttpResponseRedirect(reverse('project-list'))
308+
309+ messages.warning(request, 'Errors!')
310+ else:
311+ form = ProjectForm(owner=request.user)
312+
313+ return TemplateResponse(
314+ request, 'locolanderweb/project/add.html', context=dict(form=form))

Subscribers

People subscribed via source and target branches

to all changes: