mirror of https://github.com/snachodog/mybuddy.git
Merge pull request #19 from overshard/master
Add ability to upload picture of child with thumbnailing capabilities.
This commit is contained in:
commit
ebf42acf87
|
@ -14,3 +14,4 @@
|
||||||
# static files
|
# static files
|
||||||
/babybuddy/static
|
/babybuddy/static
|
||||||
/static
|
/static
|
||||||
|
/media
|
||||||
|
|
10
Pipfile
10
Pipfile
|
@ -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 = "*"
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"_meta": {
|
"_meta": {
|
||||||
"hash": {
|
"hash": {
|
||||||
"sha256": "8ecb16e5e548134a5bdee9b54f0f792890b2e92ebc47d219b9dfef3ea7b9dcfb"
|
"sha256": "4ff4dd2c2df1b4b46d5dc1872aa1a240f519915b1e0bf2a64b3ee650d1489fd2"
|
||||||
},
|
},
|
||||||
"requires": {},
|
"requires": {},
|
||||||
"sources": [
|
"sources": [
|
||||||
|
@ -13,7 +13,7 @@
|
||||||
},
|
},
|
||||||
"default": {
|
"default": {
|
||||||
"certifi": {
|
"certifi": {
|
||||||
"version": "==2017.7.27.1"
|
"version": "==2017.11.5"
|
||||||
},
|
},
|
||||||
"chardet": {
|
"chardet": {
|
||||||
"version": "==3.0.4"
|
"version": "==3.0.4"
|
||||||
|
@ -25,7 +25,7 @@
|
||||||
"version": "==0.4.2"
|
"version": "==0.4.2"
|
||||||
},
|
},
|
||||||
"django": {
|
"django": {
|
||||||
"version": "==1.11.6"
|
"version": "==1.11.7"
|
||||||
},
|
},
|
||||||
"django-filter": {
|
"django-filter": {
|
||||||
"version": "==1.1.0"
|
"version": "==1.1.0"
|
||||||
|
@ -34,10 +34,13 @@
|
||||||
"version": "==1.4.1"
|
"version": "==1.4.1"
|
||||||
},
|
},
|
||||||
"djangorestframework": {
|
"djangorestframework": {
|
||||||
"version": "==3.7.1"
|
"version": "==3.7.3"
|
||||||
|
},
|
||||||
|
"easy-thumbnails": {
|
||||||
|
"version": "==2.5"
|
||||||
},
|
},
|
||||||
"faker": {
|
"faker": {
|
||||||
"version": "==0.8.6"
|
"version": "==0.8.7"
|
||||||
},
|
},
|
||||||
"gunicorn": {
|
"gunicorn": {
|
||||||
"version": "==19.7.1"
|
"version": "==19.7.1"
|
||||||
|
@ -52,7 +55,7 @@
|
||||||
"version": "==2.6.0"
|
"version": "==2.6.0"
|
||||||
},
|
},
|
||||||
"jupyter-core": {
|
"jupyter-core": {
|
||||||
"version": "==4.3.0"
|
"version": "==4.4.0"
|
||||||
},
|
},
|
||||||
"nbformat": {
|
"nbformat": {
|
||||||
"version": "==4.4.0"
|
"version": "==4.4.0"
|
||||||
|
@ -60,20 +63,26 @@
|
||||||
"numpy": {
|
"numpy": {
|
||||||
"version": "==1.13.3"
|
"version": "==1.13.3"
|
||||||
},
|
},
|
||||||
|
"olefile": {
|
||||||
|
"version": "==0.44"
|
||||||
|
},
|
||||||
"pandas": {
|
"pandas": {
|
||||||
"version": "==0.20.3"
|
"version": "==0.21.0"
|
||||||
|
},
|
||||||
|
"pillow": {
|
||||||
|
"version": "==4.3.0"
|
||||||
},
|
},
|
||||||
"plotly": {
|
"plotly": {
|
||||||
"version": "==2.1.0"
|
"version": "==2.2.1"
|
||||||
},
|
},
|
||||||
"psycopg2": {
|
"psycopg2": {
|
||||||
"version": "==2.7.3.1"
|
"version": "==2.7.3.2"
|
||||||
},
|
},
|
||||||
"python-dateutil": {
|
"python-dateutil": {
|
||||||
"version": "==2.6.1"
|
"version": "==2.6.1"
|
||||||
},
|
},
|
||||||
"pytz": {
|
"pytz": {
|
||||||
"version": "==2017.2"
|
"version": "==2017.3"
|
||||||
},
|
},
|
||||||
"requests": {
|
"requests": {
|
||||||
"version": "==2.18.4"
|
"version": "==2.18.4"
|
||||||
|
@ -82,7 +91,7 @@
|
||||||
"version": "==1.11.0"
|
"version": "==1.11.0"
|
||||||
},
|
},
|
||||||
"text-unidecode": {
|
"text-unidecode": {
|
||||||
"version": "==1.0"
|
"version": "==1.1"
|
||||||
},
|
},
|
||||||
"traitlets": {
|
"traitlets": {
|
||||||
"version": "==4.3.2"
|
"version": "==4.3.2"
|
||||||
|
@ -96,13 +105,13 @@
|
||||||
},
|
},
|
||||||
"develop": {
|
"develop": {
|
||||||
"certifi": {
|
"certifi": {
|
||||||
"version": "==2017.7.27.1"
|
"version": "==2017.11.5"
|
||||||
},
|
},
|
||||||
"chardet": {
|
"chardet": {
|
||||||
"version": "==3.0.4"
|
"version": "==3.0.4"
|
||||||
},
|
},
|
||||||
"coverage": {
|
"coverage": {
|
||||||
"version": "==4.4.1"
|
"version": "==4.4.2"
|
||||||
},
|
},
|
||||||
"coveralls": {
|
"coveralls": {
|
||||||
"version": "==1.2.0"
|
"version": "==1.2.0"
|
||||||
|
|
|
@ -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')
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{% load widget_tweaks %}
|
{% load widget_tweaks %}
|
||||||
|
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<form role="form" method="post">
|
<form role="form" method="post" enctype="multipart/form-data">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
{% if form.non_field_errors %}
|
{% if form.non_field_errors %}
|
||||||
{% for error in form.non_field_errors %}
|
{% for error in form.non_field_errors %}
|
||||||
|
@ -21,4 +21,4 @@
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
<button type="submit" class="btn btn-primary">Submit</button>
|
<button type="submit" class="btn btn-primary">Submit</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -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,9 @@ 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
|
||||||
|
)
|
||||||
|
|
|
@ -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',
|
||||||
|
|
|
@ -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/'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -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()
|
||||||
|
|
||||||
|
|
|
@ -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 %}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
{% extends 'babybuddy/page.html' %}
|
{% extends 'babybuddy/page.html' %}
|
||||||
{% load widget_tweaks %}
|
{% load widget_tweaks static 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,20 @@
|
||||||
<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>
|
{% if child.picture %}
|
||||||
<td>{{ child.birth_date }}</td>
|
{% thumbnail child.picture 40x40 upscale crop as thumb %}
|
||||||
<td class="text-center">
|
<img src="{{ thumb.url }}" class="img-fluid rounded-circle" />
|
||||||
|
{% else %}
|
||||||
|
<img src="{% static 'babybuddy/img/core/child-placeholder.png' %}" width="40" height="40" class="img-fluid rounded-circle" />
|
||||||
|
{% endif %}
|
||||||
|
</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 +71,4 @@
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -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);
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue