Add ability to upload picture of child with thumbnailing capabilities.

This commit is contained in:
Isaac Bythewood 2017-11-18 04:22:12 -05:00
parent db4a1b247a
commit bf62a4e252
10 changed files with 73 additions and 13 deletions

1
.gitignore vendored
View File

@ -14,3 +14,4 @@
# static files # static files
/babybuddy/static /babybuddy/static
/static /static
/media

10
Pipfile
View File

@ -1,8 +1,11 @@
[[source]] [[source]]
verify_ssl = true verify_ssl = true
url = "https://pypi.python.org/simple" url = "https://pypi.python.org/simple"
[packages] [packages]
django = "*" django = "*"
djangorestframework = "*" djangorestframework = "*"
django-filter = "*" django-filter = "*"
@ -13,9 +16,12 @@ faker = "*"
dj-database-url = "*" dj-database-url = "*"
gunicorn = "*" gunicorn = "*"
whitenoise = "*" whitenoise = "*"
psycopg2 = "*" "psycopg2" = "*"
easy-thumbnails = "*"
[dev-packages] [dev-packages]
coveralls = "*" coveralls = "*"
flake8 = "*" "flake8" = "*"
ipaddress = "*" ipaddress = "*"

View File

@ -28,6 +28,7 @@ INSTALLED_APPS = [
'django_filters', 'django_filters',
'rest_framework', 'rest_framework',
'widget_tweaks', 'widget_tweaks',
'easy_thumbnails',
'django.contrib.admin', 'django.contrib.admin',
'django.contrib.auth', 'django.contrib.auth',
@ -122,8 +123,12 @@ STATICFILES_FINDERS = [
STATIC_URL = '/static/' STATIC_URL = '/static/'
MEDIA_URL = '/media/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static') STATIC_ROOT = os.path.join(BASE_DIR, 'static')
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
WHITENOISE_ROOT = os.path.join(BASE_DIR, 'static', 'root') WHITENOISE_ROOT = os.path.join(BASE_DIR, 'static', 'root')

View File

@ -2,6 +2,8 @@
from __future__ import unicode_literals from __future__ import unicode_literals
from django.conf.urls import url, include from django.conf.urls import url, include
from django.conf.urls.static import static
from django.conf import settings
from django.contrib import admin from django.contrib import admin
from django.contrib.auth import views as auth_views from django.contrib.auth import views as auth_views
@ -25,3 +27,6 @@ urlpatterns = [
url(r'', include('dashboard.urls')), url(r'', include('dashboard.urls')),
url(r'', include('reports.urls', namespace='reports')), url(r'', include('reports.urls', namespace='reports')),
] ]
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

View File

@ -40,7 +40,7 @@ def set_default_duration(kwargs):
class ChildForm(forms.ModelForm): class ChildForm(forms.ModelForm):
class Meta: class Meta:
model = models.Child model = models.Child
fields = ['first_name', 'last_name', 'birth_date'] fields = ['first_name', 'last_name', 'birth_date', 'picture']
widgets = { widgets = {
'birth_date': forms.DateInput(attrs={ 'birth_date': forms.DateInput(attrs={
'class': 'datepicker-input', 'class': 'datepicker-input',

View File

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.6 on 2017-11-18 09:00
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('core', '0003_weight'),
]
operations = [
migrations.AddField(
model_name='child',
name='picture',
field=models.ImageField(blank=True, null=True, upload_to='child/picture/'),
),
]

View File

@ -75,6 +75,11 @@ class Child(models.Model):
last_name = models.CharField(max_length=255) last_name = models.CharField(max_length=255)
birth_date = models.DateField(blank=False, null=False) birth_date = models.DateField(blank=False, null=False)
slug = models.SlugField(max_length=100, unique=True, editable=False) slug = models.SlugField(max_length=100, unique=True, editable=False)
picture = models.ImageField(
upload_to='child/picture/',
blank=True,
null=True
)
objects = models.Manager() objects = models.Manager()

View File

@ -1,5 +1,5 @@
{% extends 'babybuddy/page.html' %} {% extends 'babybuddy/page.html' %}
{% load static %} {% load static thumbnail %}
{% block title %}{{ object }}{% endblock %} {% block title %}{{ object }}{% endblock %}
@ -12,7 +12,12 @@
<div class="child-detail-column"> <div class="child-detail-column">
<div class="row"> <div class="row">
<div class="col-lg-4 col-md-6 pb-3 text-center"> <div class="col-lg-4 col-md-6 pb-3 text-center">
<img src="{% static 'babybuddy/img/core/child-placeholder.png' %}" class="child-photo img-fluid rounded-circle" /> {% if object.picture %}
{% thumbnail object.picture 150x150 upscale crop as thumb %}
<img src="{{ thumb.url }}" class="child-photo img-fluid rounded-circle" />
{% else %}
<img src="{% static 'babybuddy/img/core/child-placeholder.png' %}" class="child-photo img-fluid rounded-circle" />
{% endif %}
<div class="child-name display-4">{{ object }}</div> <div class="child-name display-4">{{ object }}</div>
<p class="lead"> <p class="lead">
Born <span class="text-secondary">{{ object.birth_date }}</span><br/> Born <span class="text-secondary">{{ object.birth_date }}</span><br/>
@ -58,4 +63,4 @@
</ul> </ul>
</div> </div>
</div> </div>
{% endblock %} {% endblock %}

View File

@ -1,5 +1,5 @@
{% extends 'babybuddy/page.html' %} {% extends 'babybuddy/page.html' %}
{% load widget_tweaks %} {% load widget_tweaks thumbnail %}
{% block title %}Children{% endblock %} {% block title %}Children{% endblock %}
@ -14,6 +14,7 @@
<table class="table table-striped table-hover"> <table class="table table-striped table-hover">
<thead class="thead-inverse"> <thead class="thead-inverse">
<tr> <tr>
<th><i class="fa fa-camera" aria-hidden="true"></i></th>
<th>First Name</th> <th>First Name</th>
<th>Last Name</th> <th>Last Name</th>
<th>Birth Date</th> <th>Birth Date</th>
@ -23,10 +24,16 @@
<tbody> <tbody>
{% for child in object_list %} {% for child in object_list %}
<tr> <tr>
<th scope="row"><a href="{% url 'child' child.slug %}">{{ child.first_name }}</a></th> <td>
<td>{{ child.last_name }}</td> {% thumbnail child.picture 40x40 upscale crop as thumb %}
<td>{{ child.birth_date }}</td> <img src="{{ thumb.url }}" class="img-fluid rounded-circle" />
<td class="text-center"> </td>
<th scope="row" class="align-middle">
<a href="{% url 'child' child.slug %}">{{ child.first_name }}</a>
</th>
<td class="align-middle">{{ child.last_name }}</td>
<td class="align-middle">{{ child.birth_date }}</td>
<td class="text-center align-middle">
<div class="btn-group btn-group-sm" role="group" aria-label="Actions"> <div class="btn-group btn-group-sm" role="group" aria-label="Actions">
{% if perms.core.change_child %} {% if perms.core.change_child %}
@ -60,4 +67,4 @@
</a> </a>
{% endif %} {% endif %}
{% endblock %} {% endblock %}

View File

@ -21,6 +21,12 @@ gulp.task('migrate', function(cb) {
spawn('pipenv', command, { stdio: 'inherit' }).on('exit', cb); spawn('pipenv', command, { stdio: 'inherit' }).on('exit', cb);
}); });
gulp.task('makemigrations', function(cb) {
var command = ['run', 'python', 'manage.py', 'makemigrations'];
command = command.concat(process.argv.splice(3));
spawn('pipenv', command, { stdio: 'inherit' }).on('exit', cb);
});
gulp.task('reset', function(cb) { gulp.task('reset', function(cb) {
spawn( spawn(
@ -42,4 +48,4 @@ gulp.task('runserver', function(cb) {
var command = ['run', 'python', 'manage.py', 'runserver']; var command = ['run', 'python', 'manage.py', 'runserver'];
command = command.concat(process.argv.splice(3)); command = command.concat(process.argv.splice(3));
spawn('pipenv', command, { stdio: 'inherit' }).on('exit', cb); spawn('pipenv', command, { stdio: 'inherit' }).on('exit', cb);
}); });