I have a structure similar to grocery shopping baskets. The user can have many baskets, and inside each basket, there are several bags holding fruits or other types of items.
I categorize each bag by item and color, that is, each bag only holds the same type of item with the same color. I keep track of how many of that item are there. So a bag may be: "3 Red Apples", another "60 Red Cherries"
Each user may choose a favorite color, and this is stored as a UserOption
entry. I chose not to modify the built-in User
model.
I want to simplify a function for computing the total number (quantity) of items of a given color in the desired basket. When no color is given, the favorite color is picked.
I have a working function, called get_total_default_none
, that pulls the favorite color inside the function, but my question is:
Is it possible to retrieve the user's favorite color directly as the parameter's default (in the function signature), instead of running the query inside the function?
I think this (working) approach is ugly, needing to use the None
as default, and then checking the UserOption
.
When I try referring to user
(as shown immediately below), and run the shell, I get django.core.exceptions.AppRegistryNotReady: Models aren't loaded yet.
. I also tried (following advice in other questions) replacing User
with django.conf.settings.AUTH_USER_MODEL
. These did not work.
def get_total(self, color=UserOption.objects.filter(user=user)[0].favorite_color):
# ...
pass
My models are:
class Color(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
name = models.CharField(max_length=20)
def __str__(self):
return self.name
class UserOption(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
favorite_color = models.ForeignKey(Color, on_delete=models.CASCADE)
class Basket(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
name = models.CharField(max_length=30)
# THIS FUNCTION WORKS BUT IS UGLY, I THINK
def get_total_default_none(self, color=None):
if color is None:
try:
color = UserOption.objects.filter(user=self.user)[0].favorite_color
except IndexError:
print("Could not retrieve user's favorite_color")
total = 0
bags = self.bag_set.filter(color=color)
for bag in bags:
total += bag.quantity
return total
# I HOPE TO GET SOMETHING LIKE THIS WORKING:
def get_total(self, color=UserOption.objects.filter(user=user)[0].favorite_color):
# use code similar to above
pass
def __str__(self):
return self.name
class Bag(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
item_name = models.CharField(max_length=30)
color = models.ForeignKey(Color, on_delete=models.CASCADE)
quantity = models.IntegerField()
basket = models.ForeignKey(Basket, on_delete=models.CASCADE)
def __str__(self):
return self.item_name
答案 0 :(得分:0)
您可以直接访问该关系。
def get_total(self):
color = self.user.useroption_set.first()
if color:
color = color.favorite_color
如果用户没有UserOptions, first()
将返回None。