Added ability to edit parts

- installed django_crispy_forms
- added EditPartForm in part/forms.py
- Vastly simplified parts views by using class views 
  (need to do this for the other apps too!)
This commit is contained in:
Oliver 2018-04-15 01:18:12 +10:00
parent 8578c8a1a7
commit 21e3f415c6
9 changed files with 96 additions and 62 deletions

View File

@ -35,6 +35,7 @@ INSTALLED_APPS = [
'django_filters',
'rest_framework',
'simple_history',
'crispy_forms',
# Core django modules
'django.contrib.admin',
@ -144,3 +145,4 @@ MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
CRISPY_TEMPLATE_PACK = 'bootstrap'

31
InvenTree/part/forms.py Normal file
View File

@ -0,0 +1,31 @@
from django import forms
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Submit
from .models import Part
class EditPartForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(EditPartForm, self).__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.form_id = 'id-edit-part-form'
self.helper.form_class = 'blueForms'
self.helper.form_method = 'post'
#self.helper.form_action = 'submit'
self.helper.add_input(Submit('submit', 'Submit'))
class Meta:
model = Part
fields = [
'category',
'name',
'description',
'IPN',
'URL',
'minimum_stock',
'trackable',
]

View File

@ -73,6 +73,9 @@ class Part(models.Model):
and can be combined to form other parts
"""
def get_absolute_url(self):
return '/part/{id}/'.format(id=self.id)
# Short name of the part
name = models.CharField(max_length=100)

View File

@ -0,0 +1,2 @@
{% extends 'part/part_base.html' %}

View File

@ -6,5 +6,10 @@
Part details go here...
<br>
<a href="{% url 'part-edit' part.id %}"><button class="btn btn-info">Edit Part</button></a>
<a href="{% url 'part-delete' part.id %}"><button class="btn btn-danger">Delete Part</button></a>
{% endblock %}

View File

@ -0,0 +1,11 @@
{% extends "part/part_base.html" %}
{% block details %}
Edit part information:
{% load crispy_forms_tags %}
{% crispy form %}
{% endblock %}

View File

@ -39,12 +39,17 @@ bom_api_urls = [
]
part_detail_urls = [
url(r'^track/?', views.track, name='part-track'),
url(r'^bom/?', views.bom, name='part-bom'),
url(r'^stock/?', views.stock, name='part-stock'),
url(r'^used/?', views.used, name='part-used-in'),
url(r'^suppliers/?', views.suppliers, name='part-suppliers'),
url('', views.detail, name='part-detail'),
url(r'^edit/?', views.PartEdit.as_view(), name='part-edit'),
url(r'^delete/?', views.delete, name='part-delete'),
url(r'^track/?', views.PartDetail.as_view(template_name='part/track.html'), name='part-track'),
url(r'^bom/?', views.PartDetail.as_view(template_name='part/bom.html'), name='part-bom'),
url(r'^stock/?', views.PartDetail.as_view(template_name='part/stock.html'), name='part-stock'),
url(r'^used/?', views.PartDetail.as_view(template_name='part/used_in.html'), name='part-used-in'),
url(r'^suppliers/?', views.PartDetail.as_view(template_name='part/supplier.html'), name='part-suppliers'),
# Any other URLs go to the part detail page
#url(r'^.*$', views.detail, name='part-detail'),
url(r'^.*$', views.PartDetail.as_view(), name='part-detail'),
]
# URL list for part web interface
@ -52,7 +57,7 @@ part_urls = [
# Individual
url(r'^(?P<pk>\d+)/', include(part_detail_urls)),
url('list', views.index, name='part-index'),
url('list', views.PartIndex.as_view(), name='part-index'),
# ex: /part/5/
url(r'^.*$', RedirectView.as_view(url='list', permanent=False), name='part-index'),

View File

@ -1,76 +1,50 @@
# Template stuff (WIP)
from django.http import HttpResponse
from django.template import loader
from InvenTree.models import FilterChildren
from .models import PartCategory, Part
from django.shortcuts import get_object_or_404, render
from django.http import HttpResponseRedirect
from django.urls import reverse
from django.views import generic
def index(request):
template = loader.get_template('part/index.html')
from django.views.generic import DetailView, ListView
from django.views.generic.edit import UpdateView
parts = Part.objects.all()
from .forms import EditPartForm
cat = None
class PartIndex(ListView):
model = Part
template_name = 'part/index.html'
context_object_name = 'parts'
if 'category' in request.GET:
cat_id = request.GET['category']
def get_queryset(self):
self.category = self.request.GET.get('category', None)
cat = get_object_or_404(PartCategory, pk=cat_id)
return Part.objects.filter(category=self.category)
parts = parts.filter(category = cat_id)
children = PartCategory.objects.filter(parent = cat_id)
def get_context_data(self, **kwargs):
else:
parts = parts.filter(category__isnull=True)
children = PartCategory.objects.filter(parent__isnull=True)
context = super(PartIndex, self).get_context_data(**kwargs)
context = {
'parts' : parts.order_by('category__name'),
'category' : cat,
'children' : children,
}
children = PartCategory.objects.filter(parent=self.category)
return HttpResponse(template.render(context, request))
context['children'] = children
if self.category:
context['category'] = get_object_or_404(PartCategory, pk=self.category)
return context
def detail(request, pk):
#template = loader.get_template('detail.html')
part = get_object_or_404(Part, pk=pk)
return render(request, 'part/detail.html', {'part' : part})
#return HttpResponse("You're looking at part %s." % pk)
class PartDetail(DetailView):
context_object_name = 'part'
queryset = Part.objects.all()
template_name = 'part/detail.html'
def bom(request, pk):
part = get_object_or_404(Part, pk=pk)
return render(request, 'part/bom.html', {'part': part})
def used(request, pk):
part = get_object_or_404(Part, pk=pk)
return render(request, 'part/used_in.html', {'part': part})
def stock(request, pk):
part = get_object_or_404(Part, pk=pk)
return render(request, 'part/stock.html', {'part': part})
def track(request, pk):
part = get_object_or_404(Part, pk=pk)
return render(request, 'part/track.html', {'part': part})
class PartEdit(UpdateView):
model = Part
form_class = EditPartForm
template_name = 'part/edit.html'
def suppliers(request, pk):
part = get_object_or_404(Part, pk=pk)
return render(request, 'part/supplier.html', {'part' : part})
def delete(request, pk):
return HttpResponseRedirect('/part/{pk}/'.format(pk=pk))

View File

@ -4,3 +4,4 @@ django_filter==1.0.2
django-simple-history==1.8.2
coreapi==2.3.0
pygments==2.2.0
django-crispy-forms==1.7.2