I've tried a ton of different ways, but I've hit a brick wall with the logic and hoping someone on here may be able to come up with the easily.
I have a few different connected relevant models (I've tried to strip out all irrelevant fields and methods for ease of viewing):
class InventoryAddress:
def __init__(self, warehouse, location, sublocation):
self.warehouse = warehouse
self.location = location
self.sublocation = sublocation
# Product Models
class ProductMaster(models.Model):
internal_id = models.CharField(max_length=20, unique=True, primary_key=True, null=False, blank=False,
verbose_name="Internal ID")
class ShoeAttributes(models.Model):
style_id = models.CharField(max_length=20, unique=True, primary_key=True, null=False, blank=False,
verbose_name="Style ID")
product_master = models.OneToOneField(ProductMaster, related_name='ShoeAttributes', on_delete=models.CASCADE)
brand = models.CharField(max_length=30, choices=shoe_brand_choices, default=None, blank=True, null=True,
verbose_name="Brand")
class Shoe(models.Model):
sku = models.CharField(max_length=20, unique=True, primary_key=True, null=False, blank=False,
verbose_name="SKU")
product_master = models.ForeignKey(ProductMaster, blank=False, null=False, on_delete=models.CASCADE, verbose_name="Brands")
size = models.CharField(max_length=20, null=False, blank=False, verbose_name="Size")
condition = models.CharField(max_length=25, choices=shoe_condition_choices, blank=False, null=False,
verbose_name='Condition')
class InventoryItem(models.Model):
inventory_sku = models.CharField(max_length=20, unique=True, primary_key=True, null=False, blank=False,
verbose_name="Inventory SKU")
authenticated = models.CharField(max_length=2, choices=yes_no_choices, verbose_name='Authentication Status')
# GenericForeignKey for Specific Product
content_type = models.ForeignKey(ContentType, on_delete=models.PROTECT, null=True)
object_id = models.CharField(max_length=50)
content_object = GenericForeignKey('content_type', 'object_id')
def movements(self):
movements = InventoryMovement.objects.filter(inventory_item=self)
return sorted(movements, key=lambda x: x.datetime_entered, reverse=True)
def completed_movements(self):
movements = InventoryMovement.objects.filter(inventory_item=self, datetime_completed__isnull=False)
return sorted(movements, key=lambda x: x.datetime_completed, reverse=True)
def current_location(self):
movements = self.completed_movements()
if movements:
last_movement = movements[0]
loc = InventoryAddress(
warehouse=last_movement.warehouse,
location=last_movement.location,
sublocation=last_movement.sublocation
)
else:
loc = InventoryAddress(
warehouse='EXT',
location=None,
sublocation=None,
)
return loc
def current_location_display(self):
loc = self.current_location()
setattr(loc, 'warehouse', reverse_warehouse_location_vars[self.current_location().warehouse].title())
return loc
class InventoryMovement(models.Model):
movement_id = models.CharField(max_length=20, unique=True, blank=False, null=False, verbose_name='Movement ID')
warehouse = models.CharField(max_length=40, null=False, blank=False, choices=warehouse_location_choices,
verbose_name='Warehouse')
location = models.CharField(max_length=40, null=False, blank=False, verbose_name='Target Bin')
sublocation = models.CharField(max_length=40, null=False, blank=False, verbose_name='Target Position')
inventory_item = models.ForeignKey(InventoryItem, null=True, on_delete=models.PROTECT,
verbose_name="Inventory Item")
I'm trying to filter for InventoryItem's based on user-inputs from html form (example below)
post_dict = {'style_id': 'CQ4227-030', 'size': '8', 'condition': 'NWB', 'warehouse': 'A',
'location': 'G', 'sublocation': '2'}
It seems like there are two sets of problems. The first being how to reverse generic relationships and foreign keys for their attributes (when looking for style_id, size, condition) and the second being how to filter based on a method outcome (InventoryItem.current_location() method for warehouse, location, sublocation)
I've tried a bunch of different methods (querysets, managers, list comprehension), but just cant wrap my head around an efficient working method. If anyone can come up with a way to filter for all the above easily, it would be greatly appreciated (filter would be AND, not OR)
Your relations are a bit difficult to understand, but below is a simple example of how to use querysets with GenericForeignKeys
and GenericRelations
:
models.py
from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation
from django.contrib.contenttypes.models import ContentType
class Order(models.Model):
''' generic order class '''
# fields:
price = models.DecimcalField(...)
# generic foreign key to a product:
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE, null=True)
object_id = models.PositiveIntegerField(null=True)
product = GenericForeignKey('content_type', 'object_id')
class Shirt(models.Model):
''' shirt class representing shirts available for sale '''
# fields:
color = models.CharField(...)
# generic relation:
order = GenericRelation('Order', related_query_name='shirt')
class Shoe(models.Model):
''' shoe class representing shoes available for sale '''
# fields:
size = models.CharField(...)
# generic relation:
order = GenericRelation('Order', related_query_name='shoe')
Then we can do this:
views.py
# create a new order with a shirt:
blue_shirt = Shirt.objects.get(color='blue')
order = Order.objects.create(price=10.00, product=blue_shirt)
# lookup orders with a given shirt:
orders_with_blue_shirt = Order.objects.filter(shirt=blue_shirt)
# lookup orders with a given shoe:
orders_with_large_shoe = Order.objects.filter(shoe__size='large')
# find all shirts that were on orders with a price larger than 10.00:
shirts_over_10 = Shirt.objects.filter(order__price__gt = 10.00)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.