Hi!
So... Let's suppose I'm running a Pizzeria, and I have the following models:
class Topping(models.Model):
name = models.CharField(max_length=30)
class Pizza(models.Model):
name = models.CharField(max_length=50)
toppings = models.ManyToManyField(Topping)
My goal is to fetch my Pizzas, serialize them, and store it into an ElasticSearch cluster.
If I want to fetch all my Pizzas from DB, I run the following:
pizzas = Pizza.objects.all()
But also with the Pizza object, I want to (pre)fetch all toppings. In that case, I should run:
Pizza.objects.all().prefetch_related('toppings')
This works great, but I might want to add some filters to the toppings fetched for any reason (They are out of stock, for example). I can do this by adding the field in_stock to my model Topping:
class Topping(models.Model):
name = models.CharField(max_length=30)
in_stock = models.BooleanField()
With this Topping model, I can use the Prefetch object:
pizzas = Pizza.objects.all().prefetch_related(
Prefetch('toppings', queryset=Topping.objects.filter(in_stock=True)
)
Until now everything works as expected (even the serialization). But my problem begins when I try to do the same stock control with the Pizza object. Just like I did with Topping, I will also add the in_stock field to the Pizza Model. The new Pizza Model then is:
class Pizza(models.Model):
name = models.CharField(max_length=50)
toppings = models.ManyToManyField(Topping)
in_stock = models.BooleanField()
If my Pizza is out of stock, I don't need to know which toppings are available and which are not. After the query execution I expected a list of all Pizzas and, if the pizza is available, the list of Toppings available for each pizza. I wasn't able to make this behavior using the Prefetch object. As a workaround, I tried the following:
pizzas = Pizza.objects.all().prefetch_related(
Prefetch('toppings', queryset=Topping.objects.filter(in_stock=True)
)
for pizza in pizzas:
if not pizza.in_stock:
pizza.toppings = []
Running the following, Python/Django raised an error saying that I should use this instead:
But even when I the code above (that runs without raising an error), every time I serialize my pizza object, the full toppings list gets serialized instead of the empty array previously setted.
I am using an HyperlinkedModelSerializer to serialize my data.
Can anyone help me? How can I serialize the empty array instead of the list retrieved from the db?
Thanks in advance
Cesar