Django object's id isn't available after save - django

I have the following Bank model:
from django.db import models
class Bank(models.Model):
id = models.BigIntegerField(primary_key=True)
name = models.CharField(unique=True, max_length=255)
identifier = models.CharField(unique=True, max_length=255)
created_at = models.DateTimeField()
updated_at = models.DateTimeField()
class Meta:
db_table = u'bank'
app_name = 'mcif'
Now look at this:
>>> from mcif.models import *
>>> b = Bank()
>>> b.name = "wee"
>>> b.identifier = "wee"
>>> b.save()
>>> b.id
>>>
If I understand how Django works, that Bank object is supposed to get updated with the id of the saved record. Any idea why this isn't happening?

Its a problem in Django when dealing with BigInt as Autoincrementing PK. Maybe this code snippet helps you solve this issue. Its a makeshift solution

Related

Can't access all data from prefetch_related, only the first array item?

I have the following three models that are in a many-to-many relationship:
PokemonTypesTest and BasePokemonTest are linked via an intermediary table WeakResistImmune
class PokemonTypesTest(models.Model):
name = models.CharField(max_length=25, unique=True)
def __str__(self):
return self.name
class BasePokemonTest(models.Model):
name = models.CharField(max_length=50, unique=True)
base_hp = models.IntegerField()
base_atk = models.IntegerField()
base_def = models.IntegerField()
base_spatk = models.IntegerField()
base_spdef = models.IntegerField()
base_speed = models.IntegerField()
type1 = models.ForeignKey(PokemonTypesTest, null=True, on_delete=models.SET_NULL, related_name='pokemontype1')
type2 = models.ForeignKey(PokemonTypesTest, null=True, on_delete=models.SET_NULL, related_name='pokemontype2')
type3 = models.ForeignKey(PokemonTypesTest, null=True, on_delete=models.SET_NULL, related_name='pokemontype3')
ability1 = models.CharField(max_length=25, default='n/a') #these abilities (ability1, ability2 and hidden_ability will need to be moved to a many-to-many table)
ability2 = models.CharField(max_length=25, default='n/a') #where a pokemon id from basepokemon table is linked to a ability id
hidden_ability = models.CharField(max_length=40, default='n/a')
pokemon_id = models.IntegerField(default=0)
weaknessResistanceImmune = models.ManyToManyField(PokemonTypesTest, through='WeakResistImmune')
class WeakResistImmune(models.Model):
#in the typing field, 1 is weakness
pokemon = models.ForeignKey(BasePokemonTest, on_delete=models.CASCADE)
weak_resist_immune = models.CharField(max_length=25)
typing = models.ForeignKey(PokemonTypesTest, on_delete=models.CASCADE)
multiplier = models.DecimalField(max_digits=5, decimal_places=2)
def __str__(self):
return str(self.pokemon.name)
I was going through the docs and thought the following would work:
data = BasePokemonTest.objects.prefetch_related('weaknessResistanceImmune')
Data returns the following query set
<QuerySet [<BasePokemonTest: Base for - Bulbasaur>, <BasePokemonTest: Base for - Ivysaur>, <BasePokemonTest: Base for - Venusaur>, <BasePokemonTest: Base for - Mega Venusaur>, <BasePokemonTest: Base for - Charmander>]>
I used the prefetch on the many-to-many relationship field in the BasePokemonTest model.
However, when I try to access data, I get an error-
>>> data[0]
<BasePokemonTest: Base for - Bulbasaur>
>>> data[0].weaknessResistanceImmune
<django.db.models.fields.related_descriptors.create_forward_many_to_many_manager.<locals>.ManyRelatedManager object at 0x00000235D117BD30>
>>> data[0].weaknessResistanceImmune.weak_resist_immune
Traceback (most recent call last):
File "<console>", line 1, in <module>
AttributeError: 'ManyRelatedManager' object has no attribute 'weak_resist_immune'
Not sure where I am messing up lol. Any help would be appreciated!
EDIT
heres some more info below. It looks like for whatever reason, the prefetch isn't working as intended.
It's only grabbing one type entry? Instead of all the relationships
>>> for i in data:
... print(i)
...
Base for - Bulbasaur
Base for - Ivysaur
Base for - Venusaur
Base for - Mega Venusaur
Base for - Charmander
>>> for i in data:
... print(i.weakness_resistance_immune.all())
...
<QuerySet [<PokemonTypesTest: Flying>]>
<QuerySet []>
<QuerySet []>
<QuerySet []>
<QuerySet []>

django shell - some querysets are empty in the shell but they shouldn't be

I am using the django shell to look at some querysets. I am able to retrieve all of my Student objects with .all() but if I then try to retrieve one object with .get() or filter on a field, I'm getting empty returns. The project seems to run ok on the browser (I'm still in the progress of writing all my tests but functionally it is working). I am able to successfully use get() or filter on a field with my Objectivemodel.
Here is what I get with all():
>>> from gradebook.models import Student, Objective
>>> s = Student.objects.all()
>>> for i in s:
... print(i.student_first)
...
John
Sally
Keith
Terrance
Henry
Analise
Ron
>>>
Now if I try to use get():
>>> qs = Student.objects.get(student_first='Analise')
Traceback (most recent call last):
gradebook.models.Student.DoesNotExist: Student matching query does not exist.
Or filter on a field:
>>> s.filter(student_first='Ron')
<QuerySet []>
>>>
Student model
class Student(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
user = models.OneToOneField(
settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
student_first = models.CharField(max_length=30)
student_last = models.CharField(max_length=30)
nickname = models.CharField(max_length=31)
fullname = models.CharField(max_length=60)
attend = models.BooleanField(default=True)
student_number = models.IntegerField()
email = models.EmailField(max_length=50)
def __str__(self):
return self.fullname

Django: select data from 2 models

Good day!
I have 2 models and I am trying to get sql equivalent of : select * from both models where order=xx. Appreciate little assistance :)
class Orders(models.Model):
order_id = models.AutoField(primary_key=True)
created = models.DateTimeField(auto_now_add=True)
class ResourcePool(models.Model):
email = models.EmailField()
item_a = models.CharField()
item_b = models.CharField()
item_c = models.CharField()
order_id = models.ForeignKey(Orders)
Tried the following, but it does not inlude fields from 'Orders' model
ResourcePool.objects.filter(order_id__pk=26).values()
ResourcePool.objects.filter(order_id__pk=26).select_related().values()
ResourcePool.objects.filter(order_id__pk=26).values('orders__created','email','item_a',item_b','item_c')
try this
try this
order = Orders.objects.get(pk=26)
resource=ResourcePool.objects.filter(order_id=order.id).select_related()
And to obtain the data of "Orders"
id_order_pk26 = resource.order_id.order_id
created_pk26 = resource.order_id.created

get extra field value in Django's many-to-many relationship

In Django's many-to-many relationships extra fields, we can add extra fields, as the code below (from https://docs.djangoproject.com/en/dev/topics/db/models/#intermediary-manytomany), my question is how could I get the extra field easily, is it possible to not query on the intermediary table directly? the exactly example is:
>>> ringo = Person.objects.create(name="Ringo Starr")
>>> paul = Person.objects.create(name="Paul McCartney")
>>> beatles = Group.objects.create(name="The Beatles")
>>> m1 = Membership(person=ringo, group=beatles,
... date_joined=date(1962, 8, 16),
... invite_reason="Needed a new drummer.")
>>> m1.save()
>>> beatles.members.all()
[<Person: Ringo Starr>]
>>> p = beatles.members.all()[0]
>>> p
[<Person: Ringo Starr>]
I want to get the date_joined value of p, I know it can be done by
>>> Membership.objects.get(person=p, group=beatles).date_joined
datetime.date(1962, 8, 16)
but is it possible to get it simply just like:
>>> p.xxx(*args)
=============== models.py ================
from django.db import models
class Person(models.Model):
name = models.CharField(max_length=128)
def __str__(self): # __unicode__ on Python 2
return self.name
class Group(models.Model):
name = models.CharField(max_length=128)
members = models.ManyToManyField(Person, through='Membership')
def __str__(self): # __unicode__ on Python 2
return self.name
class Membership(models.Model):
person = models.ForeignKey(Person)
group = models.ForeignKey(Group)
date_joined = models.DateField()
invite_reason = models.CharField(max_length=64)
From the documentation page you link to:
Another way to access the same information is by querying the many-to-many reverse relationship from a Person object:
>>> ringos_membership = ringo.membership_set.get(group=beatles)
>>> ringos_membership.date_joined
datetime.date(1962, 8, 16)
>>> ringos_membership.invite_reason
'Needed a new drummer.'

Querying records not in through table

Resuing Django example:
from django.db import models
class Publication(models.Model):
title = models.CharField(max_length=30)
class Article(models.Model):
headline = models.CharField(max_length=100)
publications = models.ManyToManyField(Publication)
How to I obtain all Articles that do not have publications?
Article.objects.filter(...)
Specify publications as None:
Article.objects.filter(publications=None)
Example:
>>> p1 = Publication.objects.create(title='1')
>>> p2 = Publication.objects.create(title='2')
>>> a1 = Article.objects.create(headline='a')
>>> a2 = Article.objects.create(headline='b')
>>> a3 = Article.objects.create(headline='c')
>>> a1.publications.add(p1)
>>> a1.publications.add(p2)
>>> a3.publications.add(p1)
>>> Article.objects.filter(publications=None)
[<Article: Article object>]
>>> _[0].headline
u'b'
Article.objects.filter(publications=None)
Define blank=True with publications field into Article model else it will not allow you to create article without publications.
publications = models.ManyToManyField(Publication, blank=True)