how to copy an object using multi table inheritance in django - django

I am trying to copy an object that extends another object through multi table inheritance.
The parent is Group and the child is Location
The problem is that the parent object is changed instead of creating a new parent and child object.
Here is what I am doing:
location = get_object_or_404(Location, pk=pk)
location.pk = None
location.name = location.name+' - child object'
location.save()
Instead of creating a new location and group row in their respective tables, this updates the group table to have the name = name + ' - child object'.
how can I have this process create a new location and group row instead of updating the Group row?
Thanks!

The key here is that multi-table inheritance in Django is implemented using foreign keys, so an object that "inherits" another model is simply ForeignKey'ed to that other model. You'll need to duplicate both.
For how to do so, check out the solution in this answer.

Related

Django - Delete particular field data from model

I am trying to delete a field's data from Django model. Suppose I have a model named UserData and I want to delete city field for record_Id = 1, without deleting the data from other fields for record_Id = 1. I used:
UserData.objects.filter(city="London").delete()
but it deletes the whole record. I tried this method on SO, but gives attribute error Delete field from standard Django model .
Let me know how to do this. Thanks!
When you want to delete the value of specific field in a row, then it is termed as updating the field's content to null value and not deleting the field. In this case, if you want to update the field's value to null, use following statement.
UserData.objects.filter(record_Id=1).update(city=None)

Django insert or update in one table should reflect in another table

I am trying to create a cart using django-carton App. I have two models: Halls and Caterer. I want to add either of these Halls or Caterer object in cart when I will call add() method. While using this API, I need to register my model in settings.py as below
CART_PRODUCT_MODEL = 'marriage_halls.models.Hall'
I can register only one model at a time. So I can't add Caterer object in the cart.To resolve this issue, I'm planning to create new 'product' model which will contain 3 columns viz. {name, price, city}. These are the columns which are common in both Hall and Caterer and I want to display them when I'll call show() method. My first question is, is it a correct way to do it?
If its a correct approach, What I want to do is, whenever I will add new Hall or Caterer in their respective tables through Django's admin interface, only these 3 column values should get inserted to Product table (INSERT new row in product table).
How can I achieve this?
Make Product a base class and use multi table inheritance.
https://docs.djangoproject.com/en/1.10/topics/db/models/#multi-table-inheritance

Change Django model relations without saving them

I want to change properties from related models of a certain model, but I don't want to save them, I just want to change them temporarily.
Take for example these models:
class Duck(models.Model):
name = models.StringField()
class Duckling(models.Model):
name = models.StringField()
parent = models.ForeignKey(Duck, related_name='children')
Now assume there is some data in the database, then when you try this:
for duckling in some_duck.children.all():
duckling.name = 'test-to-change-name'
for duckling in some_duck.children.all():
print(duckling.name)
In the second for loop it will print the original names and not the names we set in the first for loop. If you would save() them in the first for loop, it would work, but I want to change their names temporarily, just for this process.
Does anyone have an idea if this might be possible somehow? I was thinking of maybe overwriting some_duck.children, but then I would need to create a RelatedManager object myself, which is kind of weird and probably hacky. I hope there are better ways.
Edit: I want it to be updated on the some_duck object, so that when you access some_duck.children that you get the updated data over there.
How about converting the children queryset to a list?
children = list(some_duck.children.all())
for duckling in children:
duckling.name = 'test-to-change-name'
for duckling in children:
print(duckling.name)

Django replicating a model object causing issue

I have a 2 models with a foreign/Primary key to same model.
model Foo:
FK(Too, pk)
model Coo:
FK(Too, pk)
model Too:
blah = charfield()
In the views I am seeing some very strange behavior. I think I am doing something very wrong.
I want to replicate a object of Too and then save it. For e.g.
too = Too.create(blah="Awesome")
too.save()
foo = Foo.create(too=too)
foo.save()
too.id = None #Copy the original
too.save()
coo = Coo.create(too=too)
coo.save()
print foo.too.id
print coo.too.id
#above 2 print statements give same id
When I check in the admin the both foo and coo have different too object saved. But while printing it is showing the same. Why is that happening. I think I am doing something fundamentally wrong.
Django looks at the primary key to determine uniqueness, so work with that directly:
too.pk = None
too.save()
Setting the primary key to None will cause Django to perform an INSERT, saving a new instance of the model, rather than an UPDATE to the existing instance.
Source: https://stackoverflow.com/a/4736172/1533388
UPDATE: err, using pk and id are interchangeable in this case, so you'll get the same result. My first answer didn't address your question.
The discrepancy here is between what is occurring in python vs. what can be reconstituted from the database.
Your code causes Django to save two unique objects to the database, but you're only working with one python Too instance. When foo.save() occurs, the database entry for 'foo' is created with a reference to the DB entry for the first Too object. When coo.save() occurs, the database entry for 'coo' is created, pointing to the second, unique Too object that was stored via:
too.id = None #Copy the original
too.save()
However, in python, both coo and foo refer to the same object, named 'too', via their respective '.too' attributes. In python, there is only one 'Too' instance. So when you update too.id, you're updating one object, referred to by both coo and foo.
Only when the models are reconstituted from the database (as the admin view does in order to display them) are unique instances created for each foreign key; this is why the admin view shows two unique saved instances.

Django model object with foreign key creation

Hi
Suppose I have a simple model class like this:
class TestModel(models.Model):
testkey = models.ForeignKey(TestModel2)
...
When I am creating a TestModel object I have to pass to it an instance of the TestModel2 object to create it:
testkey =TestModel2.objects.get(id=...)
TestModel.objects.create(testkey=testkey)
This results in 2 queries to database I suppose, and I have a list of Foreign key IDs that I need to create objects with.
Is it possible to create objects with foreign keys without initially retrieving the foreign key objects?
What you’re after is:
TestModel.objects.create(testkey_id=1)
In my case TestModel.objects.create(testkey__id=1) didn't work for me so I had to put one underscore instead of two, for example
TestModel.objects.create(testkey_id=1)
In get_or_create it will fail in get. So to make get_or_create work below is the solution:
TestModel.objects.get_or_create(testkey=TestModel2(id=1))
Reference:
https://code.djangoproject.com/ticket/13915