Given the following models in a Django 2.2 app:
class ShelfPosition(models.Model):
shelf_code = models.CharField(max_length=10)
row = models.IntegerField()
column = models.IntegerField()
class Meta:
constraints = [
models.UniqueConstraint(fields=["shelf_number", "row", "column"], name="shelfpos_unique")
]
class Item(models.Model):
name = models.CharField(max_length=255)
position = models.OneToOneField(to=ShelfPosition, on_delete=models.SET_NULL, primary_key=True)
I rely on Django's lookup feature to filter on Item
objects depending on some ShelfPosition
fields:
Item.objects.filter(position__shelf_code="BF4")
Is there any way I could implement a similar lookup functionality such as described above when using get_or_create
or update_or_create
?
item, created = Item.objects.get_or_create(
position__shelf_code="BF6",
position__row=88,
position__column=1,
defaults={……}
)
I find it less verbose than the following, even if with this example it's not really relevant:
item, created = Item.objects.get_or_create(
position = Position.objects.get_or_create(
shelf_code="BF6",
row=88,
column=1
),
defaults={……}
)
Method 2: Using F Expression You can also use the F expression to do the same job. Note: You have to import the F expression before using it. Basically, these are the two methods you can use to update field in Django model.
The __str__ method in Python represents the class objects as a string – it can be used for classes. The __str__ method should be defined in a way that is easy to read and outputs all the members of the class. This method is also used as a debugging tool when the members of a class need to be checked.
To answer your question, with the new migration introduced in Django 1.7, in order to add a new field to a model you can simply add that field to your model and initialize migrations with ./manage.py makemigrations and then run ./manage.py migrate and the new field will be added to your DB. Save this answer.
The doc says: If the object's primary key attribute is set to a value that evaluates to True (i.e. a value other than None or the empty string), Django executes an UPDATE. If the object's primary key attribute is not set or if the UPDATE didn't update anything, Django executes an INSERT link.
Not sure this is what you are looking for but if you used multi-table inheritance you could achieve the following
class ShelfPosition(models.Model):
shelf_code = models.CharField(max_length=10)
row = models.IntegerField()
column = models.IntegerField()
class Meta:
unique_together = ("shelf_code", "row", "column")
class Item(ShelfPosition):
name = models.CharField(max_length=255)
item, created = Item.objects.get_or_create(
shelf_code="BF6",
row=88,
column=1,
defaults={
"name": "Spam",
}
)
You'd just have to make sure to pass keep_parents=True
when calling item.delete()
if you want to preserve the ShelfPosition
row as the default MTI behavior is to delete the whole ancestor chain.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With