0

My question is very similar to this question: How to modify a queryset and save it as new objects?

Say my models has following fields:

class myModel(models.Model):
    articleId = models.ForeignKey(otherModel)
    myCounter = models.IntegerField

Now, say keeping the articleId as constant, I want to save multiple rows by varying myCounter. This is what I am trying to do:

for x in range(1, 5):
    m = myModel()
    m.articleId = otherModel.objects.get(pid="some constant")
    m.myCounter = x
    m.save()
    m.id = None

As suggested by the above post (and similar others), I tried setting both 'id' and 'pk' as None. But nothing is helping.

This code is writing just one row in the database and is updating the value of myCounter. How do I commit 4 different rows?

Community
  • 1
  • 1
The Wanderer
  • 3,051
  • 6
  • 29
  • 53
  • karthikr answer below works!! But I am wondering is there a solution which is more in-line with the above for loop and re-creates a new object for each iteration? – The Wanderer Jun 23 '15 at 03:48

4 Answers4

0

You could use bulk_create for this:

an_article_object = otherModel.objects.create(name="Some Constant")
myModel.objects.bulk_create([
    myModel(articleId=an_article_object, myCounter=x) for x in range(1, 5)
])

EDIT:

To fix your issue in a loop:

article = otherModel.objects.create(name="SomeConst")
#or fetch the article object

m = myModel(articleId = article)

for x in range(1, 5):
    m.myCounter = x
    m.pk = None
    m.save()
karthikr
  • 97,368
  • 26
  • 197
  • 188
  • I tried this but unfortunately even this is not working. I am still getting just one row. Do you think articleId being the foreign key can be causing problem? – The Wanderer Jun 23 '15 at 03:42
  • No, that should not be the case. Do `print myModel.objects.count()` before and after the `bulk_create` and see how many objects are created. – karthikr Jun 23 '15 at 03:46
  • But I am wondering is there a solution which is more in-line with the above for loop and re-creates a new object for each iteration? – The Wanderer Jun 23 '15 at 03:48
  • sure, check the edit.. However, `bulk_create` would do 1 database write, instead of `n` in the for loop. – karthikr Jun 23 '15 at 03:48
  • well that's what my initial question was. Doing m.pk=None wasn't working. And i think this is exactly what they were discussing in the linked SO question. – The Wanderer Jun 23 '15 at 03:52
  • Oh by the way. Thanks for the help. – The Wanderer Jun 23 '15 at 03:52
  • `m.articleId` should be assigned an object, not a string. Did you try assigning an object? – karthikr Jun 23 '15 at 03:53
  • I am really sleepy, I might not reply after this for a few hours, but do try it the way shown in my edit (for loop). Reset the pk before save . – karthikr Jun 23 '15 at 03:57
0

Model -

    myCounter = models.AutoField(primary_key=True)
    #myCounter = models.AutoField(primary_key=False)

    #you use primary_key = True if you do not want to use default field "id" given by django to your model

Code -

  for x in range(1, 5):
    m = myModel()
    m.articleId = "some constant"
    m.save()
Kakshil Shah
  • 3,466
  • 1
  • 17
  • 31
0

If you want to change the same object you could try this:

m = myModel()
for x in range(1, 5):
    m.articleId = otherModel.objects.get(pid="some constant")
    m.myCounter = x
    m.save()
Gocht
  • 9,924
  • 3
  • 42
  • 81
  • How is it different from what I was doing? You are not making the id = None? Even this doesn't help. – The Wanderer Jun 23 '15 at 16:31
  • Why do you want to set the `id=None` it is not possible. This is different because you will work with the sabe object `m` inside the `for`, does not matter the `m.id` value, you will have the same `object` to work with it. – Gocht Jun 23 '15 at 17:00
  • yes and because I have the same object, only one row gets (over)-written. I want 4 different rows. – The Wanderer Jun 23 '15 at 17:02
  • _If you want to change the same object you could try this:_ that's what I said. Sorry if it is not helpful. But please tell me, why do you need (or you thought) set the id value to None? – Gocht Jun 23 '15 at 17:05
  • Well I was trying different solutions. Someone suggested that doing id=None and force_insert = True will create multiple objects. I think I will go with karthikr's answer as of now. Thank you so much for you help. – The Wanderer Jun 23 '15 at 17:15
0

You can use the force_insert parameter to force an INSERT statement. This will raise an error if the insert fails, but it won't silently update an existing object.

m.save(force_insert=True)
knbk
  • 52,111
  • 9
  • 124
  • 122