Add views to Create / Edit / Delete a PartAttachment

- Buttons to edit or delete existing attachments
- Button to add a new attachment
- Fixed conflicting migrations
This commit is contained in:
Oliver Walters 2019-05-02 17:29:21 +10:00
parent 505191089f
commit 6e8c1bcc84
9 changed files with 155 additions and 45 deletions

View File

@ -177,7 +177,10 @@ class AjaxCreateView(AjaxMixin, CreateView):
# Return the PK of the newly-created object
data['pk'] = obj.pk
data['url'] = obj.get_absolute_url()
try:
data['url'] = obj.get_absolute_url()
except AttributeError:
pass
return self.renderJsonResponse(request, form, data)
@ -223,7 +226,11 @@ class AjaxUpdateView(AjaxMixin, UpdateView):
# Include context data about the updated object
data['pk'] = obj.id
data['url'] = obj.get_absolute_url()
try:
data['url'] = obj.get_absolute_url()
except AttributeError:
pass
return self.renderJsonResponse(request, form, data)

View File

@ -9,7 +9,8 @@ from InvenTree.forms import HelperForm
from django import forms
from .models import Part, PartCategory, BomItem
from .models import Part, PartCategory, PartAttachment
from .models import BomItem
from .models import SupplierPart
@ -44,6 +45,18 @@ class BomExportForm(HelperForm):
]
class EditPartAttachmentForm(HelperForm):
""" Form for editing a PartAttachment object """
class Meta:
model = PartAttachment
fields = [
'part',
'attachment',
'comment'
]
class EditPartForm(HelperForm):
""" Form for editing a Part object """

View File

@ -14,5 +14,10 @@ class Migration(migrations.Migration):
model_name='part',
name='active',
field=models.BooleanField(default=True, help_text='Is this part active?'),
),
migrations.AddField(
model_name='partattachment',
name='comment',
field=models.CharField(blank=True, help_text='File comment', max_length=100),
),
]

View File

@ -1,18 +0,0 @@
# Generated by Django 2.2 on 2019-04-28 12:31
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('part', '0011_auto_20190428_0841'),
]
operations = [
migrations.AddField(
model_name='partattachment',
name='comment',
field=models.CharField(blank=True, help_text='File comment', max_length=100),
),
]

View File

@ -1,18 +0,0 @@
# Generated by Django 2.2 on 2019-04-30 23:34
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('part', '0013_auto_20190429_2229'),
]
operations = [
migrations.AddField(
model_name='partattachment',
name='comment',
field=models.CharField(blank=True, help_text='Attachment description', max_length=100),
),
]

View File

@ -0,0 +1,3 @@
Are you sure you wish to delete this attachment?
<br>
This will remove the file '{{ attachment.basename }}'.

View File

@ -7,7 +7,8 @@
<h4>Attachments</h4>
<div id='toolbar'>
<div id='toolbar' class='btn-group'>
<button type='button' class='btn btn-success' id='new-attachment'>Add Attachment</button>
</div>
<table class='table table-striped table-condensed' data-toolbar='#toolbar' id='attachment-table'>
@ -21,8 +22,10 @@
<td><a href='/media/{{ attachment.attachment }}'>{{ attachment.basename }}</a></td>
<td>{{ attachment.comment }}</td>
<td>
<button type='button' class='btn btn-primary' data-toggle='tooltip' title='Edit attachment ({{ attachment.basename }})'><span class='glyphicon glyphicon-edit'></span></button>
<button type='button' class='btn btn-danger' data-toggle='tooltip' title='Delete attachment ({{ attachment.basename }})'><span class='glyphicon glyphicon-trash'></span></button>
<div class='btn-group' style='float: right;'>
<button type='button' class='btn btn-primary attachment-edit-button' url="{% url 'part-attachment-edit' attachment.id %}" data-toggle='tooltip' title='Edit attachment ({{ attachment.basename }})'>Edit</button>
<button type='button' class='btn btn-danger attachment-delete-button' url="{% url 'part-attachment-delete' attachment.id %}" data-toggle='tooltip' title='Delete attachment ({{ attachment.basename }})'>Delete</button>
</div>
</td>
</tr>
{% endfor %}
@ -33,4 +36,27 @@
{% block js_ready %}
{{ block.super }}
$("#new-attachment").click(function() {
launchModalForm("{% url 'part-attachment-create' %}?part={{ part.id }}");
});
$("#attachment-table").on('click', '.attachment-edit-button', function() {
var button = $(this);
launchModalForm(button.attr('url'),
{
success: function() {
}
});
});
$("#attachment-table").on('click', '.attachment-delete-button', function() {
var button = $(this);
launchDeleteForm(button.attr('url'), {
success: function() {
}
});
});
{% endblock %}

View File

@ -1,5 +1,11 @@
"""
URL lookup for Part app
URL lookup for Part app. Provides URL endpoints for:
- Display / Create / Edit / Delete PartCategory
- Display / Create / Edit / Delete Part
- Create / Edit / Delete PartAttachment
- Display / Create / Edit / Delete SupplierPart
"""
from django.conf.urls import url, include
@ -19,6 +25,12 @@ supplier_part_urls = [
url(r'^(?P<pk>\d+)/', include(supplier_part_detail_urls)),
]
part_attachment_urls = [
url('^new/?', views.PartAttachmentCreate.as_view(), name='part-attachment-create'),
url(r'^(?P<pk>\d+)/edit/?', views.PartAttachmentEdit.as_view(), name='part-attachment-edit'),
url(r'^(?P<pk>\d+)/delete/?', views.PartAttachmentDelete.as_view(), name='part-attachment-delete'),
]
part_detail_urls = [
url(r'^edit/?', views.PartEdit.as_view(), name='part-edit'),
url(r'^delete/?', views.PartDelete.as_view(), name='part-delete'),
@ -70,6 +82,10 @@ part_urls = [
# Part category
url(r'^category/(?P<pk>\d+)/', include(part_category_urls)),
# Part attachments
url(r'^attachment/', include(part_attachment_urls)),
# Bom Items
url(r'^bom/(?P<pk>\d+)/', include(part_bom_urls)),
# Top level part list (display top level parts and categories)

View File

@ -13,11 +13,13 @@ from django.forms.models import model_to_dict
from django.forms import HiddenInput
from company.models import Company
from .models import PartCategory, Part, BomItem
from .models import PartCategory, Part, PartAttachment
from .models import BomItem
from .models import SupplierPart
from .forms import PartImageForm
from .forms import EditPartForm
from .forms import EditPartAttachmentForm
from .forms import EditCategoryForm
from .forms import EditBomItemForm
from .forms import BomExportForm
@ -51,6 +53,81 @@ class PartIndex(ListView):
return context
class PartAttachmentCreate(AjaxCreateView):
""" View for creating a new PartAttachment object
- The view only makes sense if a Part object is passed to it
"""
model = PartAttachment
form_class = EditPartAttachmentForm
ajax_form_title = "Add part attachment"
ajax_template_name = "modal_form.html"
def get_data(self):
return {
'success': 'Added attachment'
}
def get_initial(self):
""" Get initial data for new PartAttachment object.
- Client should have requested this form with a parent part in mind
- e.g. ?part=<pk>
"""
initials = super(AjaxCreateView, self).get_initial()
# TODO - If the proper part was not sent, return an error message
initials['part'] = Part.objects.get(id=self.request.GET.get('part'))
return initials
def get_form(self):
""" Create a form to upload a new PartAttachment
- Hide the 'part' field
"""
form = super(AjaxCreateView, self).get_form()
form.fields['part'].widget = HiddenInput()
return form
class PartAttachmentEdit(AjaxUpdateView):
""" View for editing a PartAttachment object """
model = PartAttachment
form_class = EditPartAttachmentForm
ajax_template_name = 'modal_form.html'
ajax_form_title = 'Edit attachment'
def get_data(self):
return {
'success': 'Part attachment updated'
}
def get_form(self):
form = super(AjaxUpdateView, self).get_form()
form.fields['part'].widget = HiddenInput()
return form
class PartAttachmentDelete(AjaxDeleteView):
""" View for deleting a PartAttachment """
model = PartAttachment
ajax_template_name = "part/attachment_delete.html"
context_object_name = "attachment"
def get_data(self):
return {
'danger': 'Deleted part attachment'
}
class PartCreate(AjaxCreateView):
""" View for creating a new Part object.
@ -102,7 +179,6 @@ class PartCreate(AjaxCreateView):
return form
# Pre-fill the category field if a valid category is provided
def get_initial(self):
""" Get initial data for the new Part object: