id of object is none after save in django - django

I'm looping through a list of objects and saving. I need the newly generated id or pointer id right after the save but it is None.
Here is my code:
for category in category_list:
saved_category = category.save()
print saved_category.parentCategory_ptr_id
print saved_category.id
This saves my object after the routine is run, but again, does not give me the id at this line.
here is my model:
class ParentCategory(models.Model):
name = models.CharField(max_length=255)
class Category(ParentCategory):
description = models.CharField(max_length=255)
category list was created like so:
category_list = []
for row in value_list:
category = Category(description=row.description)
category_list.append(category)
return category_list
What am I doing wrong?

The problem is with:
saved_category = category.save()
It needs to be:
category = category.save()
The original saved object in the list is the object that contains the id.

Their is no need of reassign.
category.save()
When you call save() method the object is saved into database and assign id (primary key) to the object.
Saving Objects Django Official
Other same question asked on Stackoverflow and correct answer by Daniel Roseman

I don't think the object will get saved. Seems that the object you are creating lacks sufficient data to satisfy db constraints. You might have used try-catch somewhere, you would have seen the error. Try adding blank=True, null=True to name in ParentCategory or provide a name while creating the object. I hope this works...

Related

How to dynamically select storage on the basis of model fields?

This is a duplicate question to this Django dynamic models.FileField Storage, but the question is not answered with correct solution yet.
I also have the similar use case. I need to dynamically change the storage on the basis of the model field.
I have tried using the callable for storage https://docs.djangoproject.com/en/3.1/topics/files/#using-a-callable. But I think this callable gets called before the model field values are initialized.
Edit:
Code Sample I have:
class MediaDocument(models.Model):
file_name = models.CharField(max_length=255)
object_storage_name = models.CharField(max_length=255, null=True)
file = models.FileField(upload_to=mediadocument_directory_path, storage=select_storage(object_storage_name))
I want to do something like this:
def select_storage(object_storage_name):
if object_storage_name == 'alibaba OSS':
return AlibabaStorage
else:
return MediaStorage
Please suggest how can I do this.
Luckily, got this article on internet https://medium.com/#hiteshgarg14/how-to-dynamically-select-storage-in-django-filefield-bc2e8f5883fd
It solves the similar use case.

Django: Getting category from add in view

I have this view, right:
def thisviewright(request,pk):
theadd = adds.objects.filter(id=pk)
theaddlist = adds.objects.filter(category=add.category)
return render_to_response..
And i'm trying to get the category so i display all other adds that have the same category.
As i'm not passing the category from a URL, i have to get it from the add, who's ID i am passing.
But i'm getting an error:
Queryset has no attribute Category
The model is as follows:
class adds(models.Model):
title = models.CharField(max_length=255)
category = models.ForeignKey('categories')
...
class categories(models.Model):
title = models.CharField(max_length=255)
So long question short, how do i get the related adds from the same category by using the category from the object i'm passing?
In the first line of the view, you're returning a queryset, not an object. While this queryset will contain only one objec, others constructed using a filter will have multiple members.
To return an object as opposed to a queryset with that line, use either of the following lines:
theadd = adds.objects.get(id=pk)
theadd = adds.objects.filter(id=pk)[0]
You should only ever use the first on unique indexed properties (i.e. id), as it will fail with an error if there is more than one object that matches the criterion.

Django: Store Hierarchical Data

I'm trying to store sections of a document in a Django app. The model looks like:
class Section(models.Model):
project = models.ForeignKey(Project)
parent_section = models.ForeignKey('Section', blank=True, null=True, related_name='child_set')
predecessor_section = models.ForeignKey('Section', blank=True, null=True, related_name='predecessor_set')
name = models.CharField(max_length=100)
text = models.TextField(blank=True, null=True)
I create a whole lot of sections, link them (parent_section, predecessor_section) and store them by calling each of their save methods. However, when I look into the table after saving it, the parent_section_id and the predecessor_section_id are not set, even though I had objects attached to them before saving.
I assume it has to do with the fact that some parent_section instances don't have an id assigned as their instance hasn't been stored yet, but using manual transactions couldn't solve the problem.
Any thoughts on that?
Cheers,
Max
objects do not have an id until you save them in Django ORM.
So I'd say you need to save() the object, then reference it in your parent/child sections (and re-save the sections).
However, another option to storing prec and next as pointers is to store an sequence_index (spaced by 10 to allow further inserts wiothout reordering) and order by this index.
Try doing a save() on all the objects, then update their relations, and then save() all of them again.
When you assign a foreignkey, the related (target) object's id is copied. since at the moment of assigning the relations (parent_section, predecessor_section) the related objects don't have an id yet, you get a funky result:
A = Section(name='A')
B = Section(name='B')
B.parent_section = A
A.save()
B.save()
B.parent_section # this will say A
B.parent_section_id # this will say **None**
But this should work:
A = Section(name='A')
B = Section(name='B')
A.save()
B.save()
B.parent_section = A
B.parent_section # this will say A
B.parent_section_id # this will say A.id
B.save() # don't forget this one :)

Django foreign keys cascade deleting and "related_name" parameter (bug?)

In this topic I found a good way to prevent cascade deleting of relating objects, when it's not neccessary.
class Factures(models.Model):
idFacture = models.IntegerField(primary_key=True)
idLettrage = models.ForeignKey('Lettrage', db_column='idLettrage', null=True, blank=True)
class Paiements(models.Model):
idPaiement = models.IntegerField(primary_key=True)
idLettrage = models.ForeignKey('Lettrage', db_column='idLettrage', null=True, blank=True)
class Lettrage(models.Model):
idLettrage = models.IntegerField(primary_key=True)
def delete(self):
"""Dettaches factures and paiements from current lettre before deleting"""
self.factures_set.clear()
self.paiements_set.clear()
super(Lettrage, self).delete()
But this method seems to fail when we are using ForeignKey field with "related_name" parameter.
As it seems to me, "clear()" method works fine and saves the instance of "deassociated" object. But then, while deleting, django uses another memorized copy of this very object and since it's still associated with object we are trying to delete - whooooosh! ...bye-bye to relatives :)
Database was arcitectured before me, and in somewhat odd way, so I can't escape these "related_names" in reasonable amount of time. Anybody heard about workaround for such a trouble?
What about re-reading the object again and delete that?
to_delete = self.__class__.objects.get(pk=self.pk)
to_delete.delete()
That way is the deleted object is a new fresh copy. The problem is to do all properly other stuff that the original delete() method has to do, like signal calling, return the correct value, etc...

django inner join query

I am working with django and having a hard time grasping how to do complex queries
Here is my model
class TankJournal(models.Model):
user = models.ForeignKey(User)
tank = models.ForeignKey(TankProfile)
ts = models.DateTimeField(auto_now=True)
title = models.CharField(max_length=50)
body = models.TextField()
class Meta:
ordering = ('-ts',)
get_latest_by = 'ts'
I need to pull the username given the tank object.
The user object is the one built into django.. thanks!
EDIT:
I have tried this
print User.objects.filter(tankjournal__tank__exact=id)
It seems to not pull out just the id.. and pull out everything in tankjournal and match it to the tank object
If you already have your tank object you should be able to do:
tank.user.username
To reduce the database queries you might want to consider the use of select_related(), e.g.
tanks = TankJournal.objects.all().select_related()
for tank in tanks:
username = tank.user.username
if you have a specific tank id then:
tank = TankJournal.objects.select_related().get(id=123456)
username = tank.user.username
I may be misunderstanding your question, but a request on User.objects.filter() will return a list of User objects, not User ids. What you've written looks technically correct.
Remember, though, that the model you have sets up a one-to-many between the TankProfile object and the TankJournal. In other words, a single TankProfile can be associated with more than one TankJournal, and therefore to more than one user. Given this, you're query is doing the right thing, returning more than one User.