2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-06-19 05:25:42 +00:00

Begin to add views for part models

- List BOM items
- Show category listing as linked items
- Fix some pathing issues with InvenTreeTree class
This commit is contained in:
Oliver
2018-04-13 22:36:59 +10:00
parent 77fe0dc542
commit bd46f66d6b
15 changed files with 182 additions and 25 deletions

View File

@ -4,12 +4,12 @@ from .models import PartCategory, Part
class PartAdmin(admin.ModelAdmin):
list_display = ('name', 'IPN', 'stock', 'category')
list_display = ('name', 'IPN', 'description', 'stock', 'category')
class PartCategoryAdmin(admin.ModelAdmin):
list_display = ('name', 'path', 'description')
list_display = ('name', 'pathstring', 'description')
"""
class ParameterTemplateAdmin(admin.ModelAdmin):

View File

@ -36,7 +36,7 @@ class Part(models.Model):
IPN = models.CharField(max_length=100, blank=True)
# Part category - all parts must be assigned to a category
category = models.ForeignKey(PartCategory, on_delete=models.CASCADE)
category = models.ForeignKey(PartCategory, on_delete=models.CASCADE, related_name='parts')
# Minimum "allowed" stock level
minimum_stock = models.PositiveIntegerField(default=0, validators=[MinValueValidator(0)])
@ -75,11 +75,21 @@ class Part(models.Model):
result = stocks.aggregate(total=Sum('quantity'))
return result['total']
@property
def bomItemCount(self):
return self.bom_items.all().count()
@property
def usedInCount(self):
return self.used_in.all().count()
"""
@property
def projects(self):
""" Return a list of unique projects that this part is associated with.
" Return a list of unique projects that this part is associated with.
A part may be used in zero or more projects.
"""
"
project_ids = set()
project_parts = self.projectpart_set.all()
@ -92,6 +102,6 @@ class Part(models.Model):
projects.append(pp.project)
return projects
"""

View File

@ -17,7 +17,8 @@ class PartParameterSerializer(serializers.HyperlinkedModelSerializer):
'units')
"""
class PartSerializer(serializers.HyperlinkedModelSerializer):
#class PartSerializer(serializers.HyperlinkedModelSerializer):
class PartSerializer(serializers.ModelSerializer):
""" Serializer for complete detail information of a part.
Used when displaying all details of a single component.
"""
@ -31,7 +32,8 @@ class PartSerializer(serializers.HyperlinkedModelSerializer):
'category',
'stock',
'units',
'trackable')
'trackable',
)
class PartCategorySerializer(serializers.HyperlinkedModelSerializer):
@ -42,7 +44,7 @@ class PartCategorySerializer(serializers.HyperlinkedModelSerializer):
'name',
'description',
'parent',
'path')
'pathstring')
"""
class PartTemplateSerializer(serializers.HyperlinkedModelSerializer):

View File

@ -0,0 +1,7 @@
<div id="category-path" background="#99F">
<a href="/part/list/">All</a> >
{% for path_item in category.parentpath %}
<a href="/part/list/?category={{ path_item.id }}">{{ path_item.name }}</a> >
{% endfor %}
<a href="/part/list/?category={{ category.id }}">{{ category.name }}</a>
</div>

View File

@ -0,0 +1,30 @@
<h1>Part details for {{ part.name }}</h1>
{% include "cat_link.html" with category=part.category %}
<br>
Part name: {{ part.name }}
<br>
Description: {{ part.description }}
<br>
IPN: {% if part.IPN %}{{ part.IPN }}{% else %}N/A{% endif %}
<br>
Stock: {{ part.stock }}
<br><br>
BOM items: {{ part.bomItemCount }}<br>
Used in {{ part.usedInCount }} other parts.<br>
<h2>BOM</h2>
<ul>
{% for bom in part.bom_items.all %}
<li><a href="{% url 'detail' bom.sub_part.id %}">{{ bom.sub_part.name }}</a> ({{ bom.quantity }})</li>
{% endfor %}
</ul>
<h2>Used to make</h2>
<ul>
{% for p in part.used_in.all %}
<li><a href="{% url 'detail' p.part.id %}">{{ p.part.name }}</a></li>
{% endfor %}
</ul>

View File

@ -0,0 +1,27 @@
<h1>Parts page!</h1>
{% if category %}
{% include "cat_link.html" with category=category %}
<h3>Child categories</h3>
<ul>
{% for child in category.children.all %}
<li><a href="/part/list?category={{ child.id }}">{{ child.name }}</a></li>
{% endfor %}
</ul>
{% else %}
No category!
{% endif %}
<b>Here is a list of all the parts:</b>
<table>
{% for part in parts %}
<tr>
<td><a href="{% url 'detail' part.id %}">{{ part.name }}</a></td>
<td>{{ part.description }}</td>
</tr>
{% endfor %}
</table>

View File

@ -1,8 +1,12 @@
from django.conf.urls import url
from django.views.generic.base import RedirectView
from . import views
part_cat_urls = [
app_nam='part'
# URL list for part category API
part_cat_api_urls = [
# Part category detail
url(r'^(?P<pk>[0-9]+)/?$', views.PartCategoryDetail.as_view(), name='partcategory-detail'),
@ -12,7 +16,9 @@ part_cat_urls = [
url(r'^$', views.PartCategoryList.as_view())
]
part_urls = [
# URL list for part API
part_api_urls = [
# Individual part
url(r'^(?P<pk>[0-9]+)/?$', views.PartDetail.as_view(), name='part-detail'),
@ -22,6 +28,17 @@ part_urls = [
url(r'^$', views.PartList.as_view()),
]
# URL list for part web interface
part_urls = [
# Individual
url(r'^(?P<pk>\d+)/$', views.detail, name='detail'),
# ex: /part/
url('list', views.index, name='index'),
# ex: /part/5/
url(r'^.*$', RedirectView.as_view(url='list', permanent=False), name='index'),
]
"""
part_param_urls = [
# Detail of a single part parameter

View File

@ -1,15 +1,72 @@
from django_filters.rest_framework import FilterSet, DjangoFilterBackend
# Template stuff (WIP)
from django.http import HttpResponse
from django.template import loader
from rest_framework import generics, permissions
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
from .serializers import PartSerializer
from .serializers import PartCategorySerializer
#from .serializers import PartParameterSerializer
#from .serializers import PartTemplateSerializer
"""
class IndexView(generic.ListView):
template_name = 'index.html'
context_object_name = 'parts'
def get_queryset(self):
"Return the last five published questions."
return Part.objects.all()
"""
def index(request):
template = loader.get_template('index.html')
parts = Part.objects.all()
cat = None
if 'category' in request.GET:
cat_id = request.GET['category']
cat = get_object_or_404(PartCategory, pk=cat_id)
#cat = PartCategory.objects.get(pk=cat_id)
parts = parts.filter(category = cat_id)
context = {
'parts' : parts.order_by('category__name'),
}
if cat:
context['category'] = cat
return HttpResponse(template.render(context, request))
def detail(request, pk):
#template = loader.get_template('detail.html')
part = get_object_or_404(Part, pk=pk)
return render(request, 'detail.html', {'part' : part})
#return HttpResponse("You're looking at part %s." % pk)
#def results(request, question_id):
# response = "You're looking at the results of question %s."
# return HttpResponse(response % question_id)
class PartDetail(generics.RetrieveUpdateDestroyAPIView):
"""