Source code for openPLM.plmapp.models.part
from django.db import models
from django.db.models import F
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import ugettext_noop
from openPLM.plmapp.utils import memoize_noarg
from .plmobject import (PLMObject, get_all_subclasses,
get_all_subclasses_with_level, PLMObjectQuerySet, PLMObjectManager)
# parts stuff
[docs]class PartQuerySet(PLMObjectQuerySet):
"""
A :class:`.PLMObjectQuerySet` with extra methods to annotate results
with the number of children or parents.
"""
[docs] def with_children_counts(self):
"""
Annotates results with the number of children (field ``num_children``).
"""
return self.extra(select={"num_children" :
"""
SELECT COUNT(plmapp_parentchildlink.id) from plmapp_parentchildlink
WHERE plmapp_parentchildlink.end_time IS NULL AND
plmapp_parentchildlink.parent_id = plmapp_part.plmobject_ptr_id
"""})
[docs] def with_parents_counts(self):
"""
Annotates results with the number of parents (field ``num_parents``).
"""
return self.extra(select={"num_parents" :
"""
SELECT COUNT(plmapp_parentchildlink.id) from plmapp_parentchildlink
WHERE plmapp_parentchildlink.end_time IS NULL AND
plmapp_parentchildlink.child_id = plmapp_part.plmobject_ptr_id
"""})
[docs]class PartManager(PLMObjectManager):
"""
Manager for :class:`Part`. Uses a :class:`PartQuerySet`.
"""
use_for_related_fields = True
def get_query_set(self):
return PartQuerySet(self.model)
[docs] def with_children_counts(self):
"""
Shorcut for ``self.get_query_set().with_children_counts()``.
See :meth:`PartQuerySet.with_children_counts`.
"""
return self.get_query_set().with_children_counts()
[docs] def with_parents_counts(self):
"""
Shorcut for ``self.get_query_set().with_parents_counts()``.
See :meth:`PartQuerySet.with_parents_counts`.
"""
return self.get_query_set().with_parents_counts()
[docs]class TopAssemblyManager(PartManager):
"""
A :class:`PartManager` that returns only top assemblies.
A top assemblies is a part with at least one child and no parents.
"""
def get_query_set(self):
from openPLM.plmapp.models.link import ParentChildLink
current_pcl = ParentChildLink.current_objects
return super(TopAssemblyManager, self).get_query_set().\
exclude(id__in=current_pcl.values_list("child")).\
filter(id__in=current_pcl.values_list("parent"))
[docs]class AbstractPart(models.Model):
"""
Abstract model that defines two managers:
.. attribute:: objects
default manager, a :class:`.PartManager`
.. attribute:: top_assemblies:
a :class:`TopAssemblyManager`
"""
class Meta:
abstract = True
objects = PartManager()
top_assemblies = TopAssemblyManager()
# first extends AbstractPart to inherit objects
[docs]class Part(AbstractPart, PLMObject):
"""
Model for parts
"""
class Meta:
app_label = "plmapp"
@property
def menu_items(self):
items = list(super(Part, self).menu_items)
items.extend([ugettext_noop("BOM-child"), ugettext_noop("parents"),
ugettext_noop("alternates"), ugettext_noop("doc-cad")])
return items
@property
def is_part(self):
return True
@property
def is_document(self):
return False
@memoize_noarg
[docs]def get_all_parts():
u"""
Returns a dict<part_name, part_class> of all available :class:`.Part` classes
"""
res = {}
get_all_subclasses(Part, res)
return res
@memoize_noarg
def get_all_parts_with_level():
lst = []
level="=>"
get_all_subclasses_with_level(Part, lst , level)
return lst