Django user id is null - django

I have a user in my django table - auth_user. The username = 'django' but when I check the id its None.
When I check in the tables, the id is set to 1.
Not sure why u.id is None.

The following code creates a user object but does not save it to the database:
# here u.id is None
u = User(username="django")
An id is associated to a new user object whenever it is added to the database:
# here u.id is not None
u = User.objects.create(username="django")
If the user object already exists, then it can be loaded from the database and the id attribute will be properly defined:
u = User.objects.get(username="django")

Related

Django IntegrityError manytomany field

I'm trying to implement hashtags in my django app
I have a message model with a field like this
hash_tags = models.ManyToManyField(HashTag, related_name='message_hash_tags')
And this is the HashTag model
hash_tag = models.CharField(max_length=140, primary_key=True)
And I'm setting the hashtags to the message like this
hash_tags_list = Functions.extract_hashtags(message["message"])
hash_tags = [HashTag.objects.get_or_create(hash_tag=ht) for ht in hash_tags_list]
messageObj.hash_tags.set(hash_tags)
messageObj.save()
But this errors out
django.db.utils.IntegrityError: insert or update on table "messaging_message_hash_tags" violates foreign key constraint "messaging_message_ha_hashtag_id_068959e9_fk_messaging"
DETAIL: Key (hashtag_id)=((<HashTag: HashTag object (skills)>, True)) is not present in table "messaging_hashtag".
Tho I can find the HashTag object (skills) in my messaging_hashtag table:
SELECT * FROM messaging_hashtag;
hash_tag
----------
skills
get_or_create returns a tuple which contains the object and a flag on whether the object was created or not, so something like: (obj, created)
To fix this, just extract the obj from the tuple. For example using [0] on the result:
hash_tags = [ HashTag.objects.get_or_create(hash_tag=ht)[0] for ht in hash_tags_list ]

How can I get value from user custom field

I have a calculated field in which I want to add a value from a previously created custom field by user (position, manager)
example here https://i.stack.imgur.com/Bg9uX.png
I managed to pass to the field by username using
User.current.id
How can I pass these 2 fields into a computed
tried to pass the value cfs[22]
unfortunately it didn't work out
To access a custom field value which id = 10, try this:
# Getting the current User object
u = User.current
# Accessing the value for custom field which id = 10
u.custom_field_value(10)
To assign a value to a custom field which id = 10 , this code should work:
# Getting the current User object
u = User.current
# Assigning the value 'value' to the custom field which id = 10
u.custom_field_values=({'10'=>'value'})
# Persisting the change
u.save
You can combine the methods to, for instance, assign a custom field value which id = 11 with the custom field value which id = 10:
u.custom_field_values=({'11'=>u.custom_field_value(10)})
# Remember to persist the change
u.save
The rails c can come in handy for you to explore the Object methods.

Have a custom primary key for users.id in flask-security

I want to have a custom key for the field id, for example, id_user, I've tried the following
class UserModel(db.model, UserMixin)
...
#property
def id(self):
return self.id_user
But couldn't make it work. When I try to login it sends me this message:
{
"message": "You don't have the permission to access the requested resource. It is either read-protected or not readable by the server."
}
I ended up with a nasty solution. I cloned the UserModel object, added a duplicated field for id, with the custom key I needed and told Flask-Security to use that object as the UserModel This is the function code I used:
def clone_model(model):
data = model
attr = getattr(model, "id_user")
setattr(data, "id", attr)
return data
cUserModel = clone_model(UserModel)
user_datastore = SQLAlchemyUserDatastore(db, cUserModel, Roles)
security = Security(app, user_datastore)
Hope someone find it useful
For anybody who is using Flask-Security-Too looking to change the default id column, here is my solution.
Define the User and Role Tables as usual and just define the id column depending on your preference.
class Role(db.Model, FsRoleMixin):
__tablename__ = 'role'
id = Column(String, primary_key=True)
class Users(db.Model, FsUserMixin):
__tablename__ = 'users'
id = Column(String, primary_key=True)
For me, I need to use String primary_key Column. For that to I needed to change the many-to-many relationship table (roles_users). Below is the code snippet for the same.
# Initialize the db object
db = SQLAlchemy()
# import this Class
from flask_security.models.fsqla_v2 import FsModels
# call this after creating the db object
FsModels.db = db
FsModels.user_table_name = 'users' # If you want a different table name than the default
FsModels.role_table_name = 'role'
# Create the relationship table as per your preferences
FsModels.roles_users = db.Table(
"roles_users",
Column("user_id", String, ForeignKey("users.id")),
Column("role_id", String, ForeignKey("role.id")),
)

Django: I want to auto-input field "id" for Many-to-Many tables

I got a ValueError while trying to add model instances with a many-to-many relationship.
ValueError: "(Idea: hey)" needs to have a value for field "id" before this many-to-many relationship can be used.
A lot of responses were given here, but none was helpful.My (idea) solution was to "manually" input the "id" values.
>>> import django
>>> django.setup()
>>> from myapp1.models import Category, Idea
# Notice that I manually add an "id"
>>> id2=Idea.objects.create(
... title_en='tre',
... subtitle_en='ca',
... description_en='mata',
... id=5,
... is_original=True,
... )
>>> id2.save()
>>> cat22=Category(title_en='yo')
>>> cat22.save()
>>> id2.categories.add(cat22)
>>> Idea.objects.all()
<QuerySet [<Idea: tre>]>
>>> exit()
How do i command django to auto-add the "id" field?
Note: I tried adding autoField but failed, thanks
#python_2_unicode_compatible
class Idea(UrlMixin, CreationModificationDateMixin, MetaTagsMixin):
id = models.IntegerField(primary_key=True,)
title = MultilingualCharField(_("Title"), max_length=200,)
subtitle = MultilingualCharField(_("Subtitle"), max_length=200, blank=True,)
description = MultilingualTextField(_("Description"), blank=True,)
is_original = models.BooleanField(_("Original"), default=False,)
categories = models.ManyToManyField(Category,
You're confusing two things here:
With many-to-many relationships, when connecting two objects, both objects must already be saved to the database (have a primary key), because under the hoods, Django creates a third object that points at the two objects to connect them. It can only do that if both have an id, assuming id is the primary key.
When creating an object, you don't have to explicitly set the id (actually you shouldn't). By default, a django Model will have id set as an auto field and as a primary key (you can override that by specifying your own pk, but in general there's no need to). The id is automatically created when the model is saved the first time.
You saw the error because probably one of the objects (idea or category) wasn't saved to the database before you connected them. In your code sample, you don't have to pass id=5, it will work without it, because you save id2 and category before connecting them.

Django: Check if a foreign key field has been loaded

I have two django models
class ValidName:
name = models.TextField()
class MetaSyntacticName(ValidNames):
name = models.ForeignKey(ValidName)
usages = models.IntegerField()
If I have an instance of MetaSyntacticName, can I find out if the ValidName instance it's name references has been loaded from the database without a database query?
One way to do this I could find is using a private model instance attribute _state. It has an attribute fields_cache which is a mapping: field name -> field cache.
So in your case you can check if a foreign key name has been loaded using this line:
'name' in instance._state.fields_cache
where instance is an instance of MetaSyntacticName.
The following code demonstrates that it's working:
foo = ValidName.objects.create(name='foo')
foo_meta = MetaSyntacticName.objects.create(name=foo, usages=1)
'name' in foo_meta._state.fields_cache # True
foo_meta = MetaSyntacticName.objects.get(name_id=foo.id)
'name' in foo_meta._state.fields_cache # False
# next line hits the db and loads the field 'name'
foo_meta.name
'name' in foo_meta._state.fields_cache # True
It took some time for me to hack this out so I hope this saves someone's time :)
P.S. I checked that the similar code works on Django 2.2, as _state is a private attribute it might be different between Django versions
If you call select_related, then there won't be any extra database query for prepopulating ForeignKey related objects. For example:(copy pasted from documentation):
# Hits the database.
e = Entry.objects.get(id=5)
# Hits the database again to get the related Blog object.
b = e.blog
And here’s select_related lookup:
# Hits the database.
e = Entry.objects.select_related('blog').get(id=5)
# Doesn't hit the database, because e.blog has been prepopulated
# in the previous query.
b = e.blog
You can add method like this:
class MetaSyntacticName(ValidNames):
...
def valid_name_is_cached(self):
return __class__.validname_ptr.is_cached(self)
__class__ is just MetaSyntacticName
validname_ptr - is Django descriptor which have method is_cached