29đź‘Ť
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 🙂
-1đź‘Ť
The reason it can’t find the class order is because it hasn’t been defined yet, you either need to specify it as a string as shown by Shang Wang, or change the order of them in your models.py
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
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
Changing the order has its advantages over specifying as a string since it will allow IDE’s to find usages of the class should it ever need refactoring.
Since you have foreign keys to both classes, the above won’t work and only applies to one-to-one or one-to-many relationships. Instead, it would be better to define a ManyToManyField
instead of the two foreign keys
- Sphinx and re-usable Django apps
- How can i get all models in django 1.8
- Determine if an attribute is a `DeferredAttribute` in django
- How can I escape LaTeX special characters inside django templates?
- How can I automatically let syncdb add a column (no full migration needed)
-1đź‘Ť
You have defined class Items
before use it and you have not any error.
you must define class Order
before class OrderedItem
.
- What is the right way to use angular2 http requests with Django CSRF protection?
- In django, is there a way to directly annotate a query with a related object in single query?