Home > Software design >  Is there a way to use an abstract value in field in Django Framework?
Is there a way to use an abstract value in field in Django Framework?

Time:01-20

I have a code like this:

class Food(models.Model):
    ...
    class Meta:
        abstract = True

class Pizza(Food):
    ...

class Burger(Food):
    ...

class Order(models.Model):
    ...
    food_type = models.OneToOneField(Food, on_cascade=CASCADE)

So, I'm wondering, if there is a way to set food_type, so it will point either at pizza or at burger model.

I've tried to do it like:

class Food(models.Model):
    order = models.OneToOneField(Order, on_delete=CASCADE)

    class Meta:
        abstract = True

But that allows to have both 'Burger' and 'Pizza' be connected to 'Order', and that's not what I need.

CodePudding user response:

I'm not too sure what you're trying to do, but if you want to limit an order to either have a Burger or a Pizza, you could use a CharField with given choices.

class Order(models.Model):
    FOOD_BURGER = 'BURGER'
    FOOD_PIZZA = 'PIZZA'
    FOOD_TYPES = ((TYPE_BURGER, 'Burger'), (TYPE_PIZZA, 'Pizza'))

    food_type = models.CharField(max_length=10, choices=FOOD_TYPES)

You can then check if an order is of a specific type by doing as follows:

my_order = Order.objects.get(pk=1)
if my_order.food_type == Order.FOOD_BURGER:
    # food type is a burger
elif my_order.food_type == Order.FOOD_PIZZA:
    # food type is a pizza

If you only want a Pizza object to be assigned to the order when the type is FOOD_PIZZA, you can check the class of the object.

my_pizza = Pizza.objects.get(pk=1)
my_order = Order.objects.get(pk=1)

if isinstance(my_pizza, Pizza): # my_pizza is an instance of Pizza
   my_order.food = my_pizza
   my_order.save()
else: # my pizza is not an actual Pizza
   # do something else
  • Related