mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
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:
parent
505191089f
commit
6e8c1bcc84
@ -177,7 +177,10 @@ class AjaxCreateView(AjaxMixin, CreateView):
|
|||||||
# Return the PK of the newly-created object
|
# Return the PK of the newly-created object
|
||||||
data['pk'] = obj.pk
|
data['pk'] = obj.pk
|
||||||
|
|
||||||
|
try:
|
||||||
data['url'] = obj.get_absolute_url()
|
data['url'] = obj.get_absolute_url()
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
|
||||||
return self.renderJsonResponse(request, form, data)
|
return self.renderJsonResponse(request, form, data)
|
||||||
|
|
||||||
@ -223,7 +226,11 @@ class AjaxUpdateView(AjaxMixin, UpdateView):
|
|||||||
|
|
||||||
# Include context data about the updated object
|
# Include context data about the updated object
|
||||||
data['pk'] = obj.id
|
data['pk'] = obj.id
|
||||||
|
|
||||||
|
try:
|
||||||
data['url'] = obj.get_absolute_url()
|
data['url'] = obj.get_absolute_url()
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
|
||||||
return self.renderJsonResponse(request, form, data)
|
return self.renderJsonResponse(request, form, data)
|
||||||
|
|
||||||
|
@ -9,7 +9,8 @@ from InvenTree.forms import HelperForm
|
|||||||
|
|
||||||
from django import forms
|
from django import forms
|
||||||
|
|
||||||
from .models import Part, PartCategory, BomItem
|
from .models import Part, PartCategory, PartAttachment
|
||||||
|
from .models import BomItem
|
||||||
from .models import SupplierPart
|
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):
|
class EditPartForm(HelperForm):
|
||||||
""" Form for editing a Part object """
|
""" Form for editing a Part object """
|
||||||
|
|
||||||
|
@ -14,5 +14,10 @@ class Migration(migrations.Migration):
|
|||||||
model_name='part',
|
model_name='part',
|
||||||
name='active',
|
name='active',
|
||||||
field=models.BooleanField(default=True, help_text='Is this part 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),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
@ -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),
|
|
||||||
),
|
|
||||||
]
|
|
@ -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),
|
|
||||||
),
|
|
||||||
]
|
|
3
InvenTree/part/templates/part/attachment_delete.html
Normal file
3
InvenTree/part/templates/part/attachment_delete.html
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
Are you sure you wish to delete this attachment?
|
||||||
|
<br>
|
||||||
|
This will remove the file '{{ attachment.basename }}'.
|
@ -7,7 +7,8 @@
|
|||||||
|
|
||||||
<h4>Attachments</h4>
|
<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>
|
</div>
|
||||||
|
|
||||||
<table class='table table-striped table-condensed' data-toolbar='#toolbar' id='attachment-table'>
|
<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><a href='/media/{{ attachment.attachment }}'>{{ attachment.basename }}</a></td>
|
||||||
<td>{{ attachment.comment }}</td>
|
<td>{{ attachment.comment }}</td>
|
||||||
<td>
|
<td>
|
||||||
<button type='button' class='btn btn-primary' data-toggle='tooltip' title='Edit attachment ({{ attachment.basename }})'><span class='glyphicon glyphicon-edit'></span></button>
|
<div class='btn-group' style='float: right;'>
|
||||||
<button type='button' class='btn btn-danger' data-toggle='tooltip' title='Delete attachment ({{ attachment.basename }})'><span class='glyphicon glyphicon-trash'></span></button>
|
<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>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
@ -33,4 +36,27 @@
|
|||||||
{% block js_ready %}
|
{% block js_ready %}
|
||||||
{{ block.super }}
|
{{ 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 %}
|
{% endblock %}
|
@ -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
|
from django.conf.urls import url, include
|
||||||
@ -19,6 +25,12 @@ supplier_part_urls = [
|
|||||||
url(r'^(?P<pk>\d+)/', include(supplier_part_detail_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 = [
|
part_detail_urls = [
|
||||||
url(r'^edit/?', views.PartEdit.as_view(), name='part-edit'),
|
url(r'^edit/?', views.PartEdit.as_view(), name='part-edit'),
|
||||||
url(r'^delete/?', views.PartDelete.as_view(), name='part-delete'),
|
url(r'^delete/?', views.PartDelete.as_view(), name='part-delete'),
|
||||||
@ -70,6 +82,10 @@ part_urls = [
|
|||||||
# Part category
|
# Part category
|
||||||
url(r'^category/(?P<pk>\d+)/', include(part_category_urls)),
|
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)),
|
url(r'^bom/(?P<pk>\d+)/', include(part_bom_urls)),
|
||||||
|
|
||||||
# Top level part list (display top level parts and categories)
|
# Top level part list (display top level parts and categories)
|
||||||
|
@ -13,11 +13,13 @@ from django.forms.models import model_to_dict
|
|||||||
from django.forms import HiddenInput
|
from django.forms import HiddenInput
|
||||||
|
|
||||||
from company.models import Company
|
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 .models import SupplierPart
|
||||||
|
|
||||||
from .forms import PartImageForm
|
from .forms import PartImageForm
|
||||||
from .forms import EditPartForm
|
from .forms import EditPartForm
|
||||||
|
from .forms import EditPartAttachmentForm
|
||||||
from .forms import EditCategoryForm
|
from .forms import EditCategoryForm
|
||||||
from .forms import EditBomItemForm
|
from .forms import EditBomItemForm
|
||||||
from .forms import BomExportForm
|
from .forms import BomExportForm
|
||||||
@ -51,6 +53,81 @@ class PartIndex(ListView):
|
|||||||
return context
|
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):
|
class PartCreate(AjaxCreateView):
|
||||||
""" View for creating a new Part object.
|
""" View for creating a new Part object.
|
||||||
|
|
||||||
@ -102,7 +179,6 @@ class PartCreate(AjaxCreateView):
|
|||||||
|
|
||||||
return form
|
return form
|
||||||
|
|
||||||
# Pre-fill the category field if a valid category is provided
|
|
||||||
def get_initial(self):
|
def get_initial(self):
|
||||||
""" Get initial data for the new Part object:
|
""" Get initial data for the new Part object:
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user