ForeignKey to a model that is defined after/below the current model

Issue

Having the error msg

order = models.ForeignKey(Order, on_delete=models.CASCADE)
NameError: name 'Order' is not defined

So how ever I do one class will be missing cuz of the class is below the currently reading class so that the class is missing. How do I solve this? i’ve read about many-to-many function, might that solve the problem?

class Items(models.Model):
    name = models.CharField(max_length=10)
    def __str__(self):
        return self.name    

class OrderedItem(models.Model):
    items = models.ForeignKey(Items, on_delete=models.CASCADE)
    order = models.ForeignKey(Order, on_delete=models.CASCADE)
    amount = models.IntegerField()
    def __str__(self):
        return self.items

class Order(models.Model):
    #clientID
    orderedItem = models.ForeignKey(OrderedItem, on_delete=models.CASCADE)
    #truckId Foreign key till truck
    created = models.DateTimeField(auto_now=False, auto_now_add=True)
    updated = models.DateTimeField(auto_now=True, auto_now_add=False)
    emergency = models.BooleanField(default=False)
    status = models.IntegerField()
    #building
    #floor
    def __str__(self):
        return self.id

Solution

Use the fully-qualified model string

When this happens, I usually resort to what’s called the fully-qualified model string, fancy term for what’s essential a string representing the model and the containing app in the format of 'app_label.ModelName'

E.g. if your model is Order, then the model string name would be the string 'Order'

So you can already do:

order = models.ForeignKey('Order', on_delete=models.CASCADE)

With the above, Django will look for the model 'Order' in the same app. It’s okay if you have not defined it yet, as long as it is defined.

If that model happens to come from a different app, it would be:

order = models.ForeignKey('appname.Order', on_delete=models.CASCADE)

Reverse query clashes

Because Order points to OrderItems and OrderItems point to Order you get a clash with related queries that Django generate for you. You can disable those with related_name='+':

order = models.ForeignKey('Order', on_delete=models.CASCADE, related_name='+')

Better modeling

Since a OrderedItem already “belongs” to an Order, there’s no point in having a ForeignKey from Order to OrderedItem, you can just remove it instead of dealing with the above clash.

So what you’d have would look like this

Item

Order

OrderedItem
    + FK(Item)
    + FK(Order)

A design which wouldn’t involve referencing a model that hasn’t been defined yet 🙂

Answered By – bakkal

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published