-
Notifications
You must be signed in to change notification settings - Fork 6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Homework #8
base: master
Are you sure you want to change the base?
Homework #8
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,53 +1,12 @@ | ||
# MelbDjango School Lesson Four | ||
|
||
### Assignment 1 | ||
|
||
**Important:** Check out our first assignment here: https://github.com/melbdjango/melbdjango-assignment | ||
|
||
--- | ||
|
||
|
||
Congratulations, you've made it to the git repository for our fourth lesson. Hopefully you also made it to the class | ||
and some of this makes sense to you. | ||
|
||
Check our RESOURCES.md for some links we think you'll find handy. | ||
|
||
|
||
## Homework Checklist | ||
|
||
- [ ] [Fork this repository][gh-fork] | ||
- [ ] Clone the repo to your own machine | ||
- [ ] Use the virtualenv you created in previous lesson | ||
- [ ] Create forms to create new Projects and Clients (look at our EntryForm to see how to handle ForeignKey relationships) | ||
- [ ] Add those forms to your views and templates so that users can create new Clients and Projects | ||
- [ ] Add some validation to make sure that start time is in the past | ||
- [ ] Validate that the end time is after the start time | ||
- [X] [Fork this repository][gh-fork] | ||
- [X] Clone the repo to your own machine | ||
- [X] Use the virtualenv you created in previous lesson | ||
- [X] Create forms to create new Projects and Clients (look at our EntryForm to see how to handle ForeignKey relationships) | ||
- [X] Add those forms to your views and templates so that users can create new Clients and Projects | ||
- [X] Add some validation to make sure that start time is in the past | ||
- [X] Validate that the end time is after the start time | ||
- [ ] Bonus Points #1: Think about making our form look a little nice with some CSS | ||
- [ ] Bonus Points #2: Add the ability to edit existing Projects and Clients | ||
|
||
When you've completed some or all of the homework please make a [Pull Request][gh-pr] against this repository. If you submit | ||
your work before Wednesday evening we'll give you feedback before the next class. | ||
|
||
If you'd like help, make a Pull Request with your incomplete work and ask a question to @darrenfrenkel, @sesh or | ||
@funkybob. | ||
|
||
|
||
## Displaying the class slides | ||
|
||
Install reveal-md with npm and use that to display the class slides. | ||
|
||
``` | ||
npm install -g reveal-md | ||
``` | ||
|
||
From within the `lesson-four` repo: | ||
|
||
``` | ||
cd slides | ||
reveal-md CLASS.md --theme melbdjango | ||
``` | ||
- [X] Bonus Points #2: Add the ability to edit existing Projects and Clients | ||
|
||
[gh-fork]: https://help.github.com/articles/fork-a-repo/ | ||
[gh-pr]: https://help.github.com/articles/using-pull-requests/ | ||
[dj-request-response]: https://docs.djangoproject.com/en/1.8/ref/request-response/ | ||
[mdn-html]: https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Introduction |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,34 @@ | ||
from django import forms | ||
|
||
from .models import Project | ||
|
||
from django.utils import timezone | ||
from .models import Project, Client | ||
|
||
class EntryForm(forms.Form): | ||
start = forms.DateTimeField(label="Start Time", help_text="Format: 2006-10-25 14:30") | ||
end = forms.DateTimeField(label="End Time", help_text="Format: 2006-10-25 14:30") | ||
stop = forms.DateTimeField(label="End Time", help_text="Format: 2006-10-25 14:30") | ||
project = forms.ModelChoiceField(queryset=Project.objects.all()) | ||
description = forms.CharField() | ||
|
||
def clean(self): | ||
cleaned_start = super(EntryForm,self).clean() | ||
start = cleaned_start.get("start") | ||
stop = cleaned_start.get("stop") | ||
|
||
if start and stop: | ||
if start > timezone.now(): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You could do the validation for the start time not being in the future in |
||
raise forms.ValidationError("Error:Project date exceeds current date") | ||
return start | ||
|
||
if stop < start: | ||
raise forms.ValidationError("Error: Project end date is before start date") | ||
return stop | ||
|
||
class ClientForm(forms.Form): | ||
name = forms.CharField(required=False, label="name") | ||
|
||
class ProjectForm(forms.Form): | ||
client= forms.ModelChoiceField(queryset=Client.objects.all()) | ||
name = forms.CharField(required=False, label="name") | ||
|
||
|
||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,7 +4,7 @@ | |
|
||
class Client(models.Model): | ||
name = models.CharField(max_length=200) | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You should avoid trailing spaces. |
||
def __str__(self): | ||
return self.name | ||
|
||
|
@@ -16,7 +16,6 @@ class Project(models.Model): | |
def __str__(self): | ||
return '<{}> {}'.format(self.client, self.name) | ||
|
||
|
||
# Create your models here. | ||
class Entry(models.Model): | ||
start = models.DateTimeField(default=timezone.now) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
{% extends "base.html" %} | ||
|
||
{% block title %}Clients{% endblock %} | ||
|
||
{% block content %} | ||
<h2>Clients</h2> | ||
<form method="post"> | ||
{% csrf_token %} | ||
{{ client_form.as_p }} | ||
<input type="submit" name="client_submit" value="Update Client"> | ||
</form> | ||
|
||
<ul> | ||
<li>{{ client.name }}</li> | ||
</ul> | ||
{% endblock %} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
{% extends "base.html" %} | ||
|
||
{% block title %}Projects{% endblock %} | ||
|
||
{% block content %} | ||
<h2>Projects</h2> | ||
<form method="post"> | ||
{% csrf_token %} | ||
{{ project_form.as_p }} | ||
<input type="submit" name="test" value="Update Project"> | ||
</form> | ||
|
||
<ul> | ||
<li>{{ project.name }}</li> | ||
</ul> | ||
{% endblock %} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,32 +1,54 @@ | ||
from django.shortcuts import render, get_object_or_404 | ||
from django.utils import timezone | ||
|
||
from .forms import EntryForm | ||
from .models import Client, Entry, Project | ||
from .forms import EntryForm, ProjectForm, ClientForm | ||
|
||
from .models import Client, Entry, Project | ||
|
||
def clients(request): | ||
if request.method == 'POST': | ||
client_form = ClientForm(request.POST) | ||
if client_form.is_valid(): | ||
client = Client() | ||
client.name = client_form.cleaned_data['name'] | ||
client.save() | ||
else: | ||
client_form = ClientForm(request.POST) | ||
|
||
client_list = Client.objects.all() | ||
return render(request, 'clients.html', { | ||
'client_list': client_list, | ||
'client_form': client_form, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It doesn't really make any difference, but most people only use |
||
}) | ||
|
||
|
||
def client_detail(request, pk): | ||
client = get_object_or_404(Client, pk=pk) | ||
return render(request, 'client_detail.html', { | ||
'client': client, | ||
}) | ||
|
||
def client_edit(request,pk): | ||
client = get_object_or_404(Client, pk=pk) | ||
if request.method == 'POST': | ||
client_form = ClientForm(request.POST) | ||
if client_form.is_valid(): | ||
client.name = client_form.cleaned_data['name'] | ||
client.save() | ||
else: | ||
client_form = ClientForm(initial={'name':client.name}) | ||
|
||
return render(request, 'client_edit.html', { | ||
'client': client, | ||
'client_form': client_form, | ||
}) | ||
|
||
def entries(request): | ||
if request.method == 'POST': | ||
# Create our form object with our POST data | ||
entry_form = EntryForm(request.POST) | ||
if entry_form.is_valid(): | ||
# If the form is valid, let's create and Entry with the submitted data | ||
entry = Entry() | ||
entry.start = entry_form.cleaned_data['start'] | ||
entry.end = entry_form.cleaned_data['end'] | ||
entry.stop = entry_form.cleaned_data['stop'] | ||
entry.project = entry_form.cleaned_data['project'] | ||
entry.description = entry_form.cleaned_data['description'] | ||
entry.save() | ||
|
@@ -39,9 +61,36 @@ def entries(request): | |
'entry_form': entry_form, | ||
}) | ||
|
||
|
||
def projects(request): | ||
if request.method == 'POST': | ||
project_form = ProjectForm(request.POST) | ||
if project_form.is_valid(): | ||
project = Project() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can also write project = Project(
name=project_form.cleaned_data['name'],
client=project_form.cleaned_data['client'],
)
project.save() or use |
||
project.client = project_form.cleaned_data['client'] | ||
project.name = project_form.cleaned_data['name'] | ||
project.save() | ||
else: | ||
project_form = ProjectForm(request.POST) | ||
|
||
project_list = Project.objects.all() | ||
return render(request, 'projects.html', { | ||
return render(request,'projects.html',{ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The previous code (the one marked red) was correct according to PEP 8. |
||
'project_list': project_list, | ||
'project_form': project_form, | ||
}) | ||
|
||
def project_edit(request,pk): | ||
project = get_object_or_404(Project, pk=pk) | ||
if request.method == 'POST': | ||
project_form = ProjectForm(request.POST) | ||
if project_form.is_valid(): | ||
project.client = project_form.cleaned_data['client'] | ||
project.name = project_form.cleaned_data['name'] | ||
project.save() | ||
else: | ||
project_form = ProjectForm(initial={'name':project.name}) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You don't pass a project as initial value here, thus a user has to select the value from the drop down list each time they want to edit a project. |
||
|
||
return render(request, 'project_edit.html', { | ||
'project': project, | ||
'project_form': project_form, | ||
}) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is no need to call
super()
.