diff --git a/.gitignore b/.gitignore index f3d001706f..78b657e227 100644 --- a/.gitignore +++ b/.gitignore @@ -27,3 +27,6 @@ var/ local_settings.py *.sqlite3 **/migrations/* + +# Local media storage (only when running in development mode) +InvenTree/media \ No newline at end of file diff --git a/InvenTree/InvenTree/settings.py b/InvenTree/InvenTree/settings.py index 259d7c7a22..f348cdfe04 100644 --- a/InvenTree/InvenTree/settings.py +++ b/InvenTree/InvenTree/settings.py @@ -135,3 +135,8 @@ USE_TZ = True # https://docs.djangoproject.com/en/1.10/howto/static-files/ STATIC_URL = '/static/' + +MEDIA_URL = '/media/' + +MEDIA_ROOT = os.path.join(BASE_DIR, 'media') + diff --git a/InvenTree/InvenTree/urls.py b/InvenTree/InvenTree/urls.py index 0c9c5465eb..3e09f6e5ee 100644 --- a/InvenTree/InvenTree/urls.py +++ b/InvenTree/InvenTree/urls.py @@ -76,4 +76,11 @@ urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^auth/', include('rest_framework.urls', namespace='rest_framework')), -] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) +] + +# Static file access +urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) + +if settings.DEBUG: + # Media file access + urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) \ No newline at end of file diff --git a/InvenTree/part/models.py b/InvenTree/part/models.py index 6e8f12eeae..790cd28618 100644 --- a/InvenTree/part/models.py +++ b/InvenTree/part/models.py @@ -6,6 +6,8 @@ from django.core.validators import MinValueValidator from InvenTree.models import InvenTreeTree +import os + #from django.db.models.signals.pre_delete #from django.dispatch import receiver @@ -21,15 +23,24 @@ class PartCategory(InvenTreeTree): def parts(self): return self.part_set.all() -""" -@receiver(pre_delete, sender=PartCategory) -def reset_tag(sender, **kwargs): - cat = kwargs['instance'] - for book in books.filter(tag=tag): - book.tag = book.author.tags.first() - book.save() -""" +# Function to automatically rename a part image on upload +# Format: part_pk. +def rename_part_image(instance, filename): + base = 'part_images' + + if filename.count('.') > 0: + ext = filename.split('.')[-1] + else: + ext = '' + + fn = 'part_{pk}_img'.format(pk=instance.pk) + + if ext: + fn += '.' + ext + + return os.path.join(base, fn) + class Part(models.Model): """ Represents an abstract part @@ -54,6 +65,8 @@ class Part(models.Model): null=True, blank=True, on_delete=models.SET_NULL) + image = models.ImageField(upload_to=rename_part_image, max_length=255, null=True, blank=True) + # Minimum "allowed" stock level minimum_stock = models.PositiveIntegerField(default=0, validators=[MinValueValidator(0)]) diff --git a/InvenTree/part/templates/part/part_base.html b/InvenTree/part/templates/part/part_base.html index 6f29e9fb4e..128c4e19f2 100644 --- a/InvenTree/part/templates/part/part_base.html +++ b/InvenTree/part/templates/part/part_base.html @@ -4,13 +4,26 @@ {% include "part/cat_link.html" with category=part.category %} -{{ part.name }} - -
-{{ part.description }} -
-IPN: {% if part.IPN %}{{ part.IPN }}{% else %}N/A{% endif %} -
+
+ +
+
{{ part.name }}
+ {% if part.description %} +

{{ part.description }}

+ {% endif %} + {% if part.IPN %} +

IPN: {{ part.IPN }}

+ {% endif %} + {% if part.URL %} +

{% include 'url.html' with url=part.URL %}

+ {% endif %} +
+
{% block details %} diff --git a/InvenTree/part/templates/url.html b/InvenTree/part/templates/url.html new file mode 100644 index 0000000000..16c17842f1 --- /dev/null +++ b/InvenTree/part/templates/url.html @@ -0,0 +1,7 @@ +{% if url %} + +{% if text %}{{ text }} +{% else %}{{ url }} +{% endif %} + +{% endif %} \ No newline at end of file