How to change parent class from models.Model to PolymorphicModel
I have two django models, Tomato and Potato. Both are being referenced multiple times across my project.
I recently created a foreign key field in a third model, ShoppingBag, which should be allowed to contain one instance from either Tomato or Potato.
My first approach was to create an empty (since Tomato and Potato have no fields in common) superclass Buyable, which inherits PolymorphicModel.
I then set the referenced model in ShoppingBag.myforeignkey to accept instances of Buyable and I thought that would be it.
I am now facing lots of errors, mostly because Potato.id and Tomato.id are being replaced by .buyable_ptr and the already existing foreign key and m2m fields to Potato and Tomato don't really like that.
I wanted to ask if there's an official way to face this switch between parents or an alternative, easier way to tackle this issue.
I created a function that generates a new instance of the super class and returns its id. I then set that function as the default value in the migration file. The solution didn't work, as the generated id was always 1.
import Buyable
def generate_id():
new_instance = Buyable()
new_instance.save()
return new_instance
I implemented it through model inheritance.
I didn't apply abstraction because there is no common part between Tomato and Potato.
class Vegetable(models.Model):
pass
class ShoppingBag(models.Model):
vegetable = models.ForeignKey(Vegetable, on_delete=models.SET_NULL, null=True)
class Potato(Vegetable):
potato_field = models.CharField(max_length=128)
class Tomato(Vegetable):
tomato_field = models.CharField(max_length=128)
In the code above, Tomato and Potato are also represented by a single model object called Vegatable.
That's why when we create a ShoppingBag model object, we can only select one of the objects in the Tomato and Potato models.
Colleague of mine suggested a new approach.
I will add two foreign key fields to ShoppingBag and perform an xor check in the save or the clean method to assure that only one instance is selected.