Django get_or_create returns False - python

I'm creating a population script, from an MysqlDatabase to Django Models.
Im looping through my receiving data from the Mysql and thats going good.
Now I have to write it to the Django Database...
mdl, succeeded = models.User.objects.get_or_create(
name=name,
password=password,
email=email
)
I'm printing succeeded so I can see what the feedback is, but all it gives me is False
My Django Model User is edited so all fields can be blank and allows NULL or have a default
My Model User:
username = models.CharField(max_length=20, blank=True, null=True)
slug = models.SlugField(null=True, blank=True)
email = models.EmailField(unique=True, null=True)
name = models.CharField("First and last name", max_length=100)
uses_metric = models.BooleanField(default=True)
position = models.CharField("Position", max_length=70, blank=True, null=True,)
utility = models.ForeignKey(Utility, default=1, blank=True, null=True)
supplier = models.ForeignKey(Supplier, default=1, blank=True, null=True)
currency = models.ForeignKey(Currency, default=1)
phone = models.CharField("Direct phone number", max_length=40, blank=True, default='+')
gets_notifications_on_reply = models.BooleanField("Receive notifications", default=False)
memberlist = models.BooleanField("Show member in memberslist", default=True)
registration_date = models.IntegerField(default=floor(time.time()), blank=True, null=True)
is_staff = models.BooleanField(
_('staff status'),
default=False,
help_text=_('Designates whether the user can log into this site.'),
)
is_active = models.BooleanField(
_('active'),
default=True,
help_text=_(
'Designates whether this user should be treated as active. '
'Deselect this instead of deleting accounts.'
),
)
USERNAME_FIELD = 'email'

Please check your database. This means that the User objects you are querying from there already exists. This might be due to the object already existing or alternatively your code not using the correct database. Since migrations, often use multiple databases this might be a problem as well.
According to the Django documentation, get_or_create() does not return an object and a status succeeded but instead a flag created, which indicates if this object has been newly created or already existed in the database. If it already existed, the created flag (succeeded in your code) is False.
If you want to make sure that the error is not due to objects already existing, take one data pair for which created is false and try to retrieve it using the model's get() method. If this throws a DoesNotExist error then something else is the problem. If it returns an object then that object already existed.

Related

Django, tried to add a field to exsting model raises error

I Have a Django rest framework API which contained the following model:
class Points(models.Model):
mission_name = models.CharField(name='MissionName',
unique=True,
max_length=255,
blank=False,
help_text="Enter the mission's name"
)
latitude = models.FloatField(name="GDT1Latitude",
unique=False, max_length=255, blank=False,
help_text="Enter the location's Latitude, first when extracting from Google Maps.",
default=DEFAULT_VALUE)
longitude = models.FloatField(name="GDT1Longitude",
unique=False, max_length=255, blank=False,
help_text="Enter the location's Longitude, second when extracting from Google Maps.",
default=DEFAULT_VALUE)
Added User Field:
class Points(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
# rest of fields...
Iv'e added a User field, When trying to makemigrations and migrate it I get the following error:
django.db.utils.ProgrammingError: column find_second_gdt_points.user does not exist
LINE 1: SELECT "find_second_gdt_points"."id", "find_second_gdt_point...
Which I don't get, of course, this column does not exist.
This is what migartions are for, no?
Try adding default=None,
class Points(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, default= None)
# rest of fields...
These errors are usually because you need to include a default null value for the new field, as well as allowing it to be nullable, it should be as simple as:
class Points(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, null=True, default=None)
...
The reason being, is that the migration is applied to exisiting records in your database, as well as all future records. The migration needs to know how to populate the new field (column) in the DB for existing records...

Query on a model field? Is it possible in models.py? [duplicate]

This question already has an answer here:
How to query related models in django models.py
(1 answer)
Closed 3 years ago.
I have a model called StudentProfile:
class StudentProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
class_advisor = models.CharField(max_length=50)
year = models.OneToOneField(YearLevel, on_delete=models.SET_NULL, null=True)
section = models.OneToOneField(Section, on_delete=models.SET_NULL, null=True)
what I want to happen is, class_advisor to only return and accpet User with is_teacher = True.
by the way here's my User model:
class User(AbstractUser):
email = models.EmailField(
max_length=254,
unique=True,
verbose_name='Email Address',
blank=True
)
is_student = models.BooleanField(default=False, verbose_name='Student')
is_superuser = models.BooleanField(default=False, verbose_name='Administrator')
is_teacher = models.BooleanField(default=False, verbose_name='Teacher')
is_staff = models.BooleanField(default=False, verbose_name='Staff')
is_registrar = models.BooleanField(default=False, verbose_name='Registrar')
Yes, however at the moment, something is wrong with your modeling. You should make class_advisor a ForeignKey to the user model. Imagine that you store the username (or whatever unique attribute of that user) in your model. If later that teacher changes that username, then it will refer to a non-existing user, or later to a different user that picked the username.
You can set the limit_choices_to=... parameter [Django-doc]:
from django.db.models import Q
from django.contrib.auth import get_user_model
class StudentProfile(models.Model):
user = models.OneToOneField(get_user_model(), on_delete=models.CASCADE, primary_key=True, related_name='studentprofile')
class_advisor = models.ForeignKey(get_user_model(), limit_choices_to=Q(is_teacher=True), related_name='students')
year = models.OneToOneField(YearLevel, on_delete=models.SET_NULL, null=True)
section = models.OneToOneField(Section, on_delete=models.SET_NULL, null=True)
If you use forms, etc. It will limit the options to Users that are teachers, and do validation on this.
It is better to use get_user_model() [Django-doc] here to refer to your user model, since if you later alter it, the ForeignKey (and OneToOneField will refer to the new model).
Try this:
StudentProfile.objects.filter(user__is_teacher=True)
StudentProfile.objects.filter(user__is_teacher=True).values('class_advisor')

'NoneType' object has no attribute 'add'

I have the following User object,
class User(AbstractBaseUser, PermissionsMixin, Base):
username = models.CharField(
db_index=True,
null=False,
unique=True,
max_length=255,
)
mobile = PhoneNumberField(
db_index=True,
null=False,
unique=True,
)
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
is_active = models.BooleanField(default=False)
And I've the following class to manage connections,
class Connections(Base):
owner = models.OneToOneField(
User,
on_delete=models.CASCADE,
null=True,
)
friends = models.ForeignKey(
User,
on_delete=models.CASCADE,
related_name='friend_set',
null=True,
blank=True,
)
followers = models.ForeignKey(
User,
on_delete=models.CASCADE,
related_name='follower_set',
null=True,
blank=True,
)
followings = models.ForeignKey(
User,
on_delete=models.CASCADE,
related_name='following_set',
null=True,
blank=True,
)
When I try to add a friend,
sender = User.objects.get(
id=kwargs.get('sender_id')
)
receiver = User.objects.get(
id=kwargs.get('receiver_id')
)
sender_connections, created =(
Connections.objects.get_or_create(owner=sender)
)
sender_connections.friends.add(receiver)
I get the following error,
'NoneType' object has no attribute 'add'
Can someone help me with this?
It looks like you are trying to user the django related manager add function
sender_connections.friends.add(receiver)
However the friends attribute on connections is a ForeignKey relation instead of a ManyToManyField. This means that when you call sender_connections.friends and the connection does not exist, you will get None.
If you change the attribute to a ManyToManyField, then sender_connections.friends will return a ManyRelatedManager and the add should work as expected.
Complementing the wingardtw answer, with Django 3.0 you can use PrimaryKeyRelatedField, and instead of using "add" you will perform an update on the queryset, like under:
Connections.objects.filter(owner=sender).update(friends=receiver)
Important: This requires the objects to already be saved.
See those link for more information:
https://docs.djangoproject.com/en/3.0/ref/models/relations/#django.db.models.fields.related.RelatedManager.add
https://docs.djangoproject.com/en/3.0/ref/models/querysets/#django.db.models.query.QuerySet.update

Do I need to make a migration if I change null and blank values on a Model field?

I have the following model
#python_2_unicode_compatible
class Booking(models.Model):
session = models.ForeignKey(verbose_name=_('Session'), to=Session, default=None, null=False, blank=False)
quantity = models.PositiveIntegerField(verbose_name=_('Quantity'), default=1, null=False, blank=False)
price = models.DecimalField(verbose_name=_('Price'), max_digits=10, decimal_places=2,
default=None, null=False, blank=False)
name = models.CharField(verbose_name=_('Name'), max_length=100, default=None, null=False, blank=False)
email = models.EmailField(verbose_name=_('Email'), default=None, null=True, blank=True)
phone_number = models.CharField(verbose_name=_('Phone Number'), max_length=30, default=None, null=True, blank=True)
Say I need to change my email and phone_number fields. I want them to have null=False and blank=False. Do these alterations require a new migration?
Yes they do. null=False requires a change to the database schema itself; blank=False does not, but Django needs a migration anyway so that the migration runner's internal graph of the model state is up to date.
Sure. To check it you can run python manage.py makemigrations --dry-run (the --dry-run doesn't save a new migration file, but shows if it's necessary)
https://docs.djangoproject.com/en/1.11/topics/db/models/#field-options
Django document says:
null
If True, Django will store empty values as NULL in the database. Default >is False.
blank
If True, the field is allowed to be blank. Default is False.
Note that this is different than null. null is purely database-related,
whereas blank is validation-related. If a field has blank=True, form
validation will allow entry of an empty value. If a field has blank=False,
the field will be required.
For change in null you need to migrate
For change in blank you need not to migrate, because its admin form related
Sure they do. Every change you made to your model fields (from simply altering the help_text to completely rename a model field) requires to makemigrations and migrate in order to reconstruct your model in the future.

how to change the database after changing the model?

please help, something strange happens.
I had a model:
class Feedback(models.Model):
username = models.CharField(
verbose_name=u"Имя",
max_length=100,
blank=True,
)
subject = models.CharField(
verbose_name=u"Тема",
max_length=100,
blank=False,
)
email = models.EmailField(
verbose_name=u"Email",
max_length=100,
blank=True,
)
message = models.TextField(
verbose_name=u'Сообщение',
max_length=50000,
blank=False,
)
date = models.DateTimeField(
verbose_name=u'Дата создания',
default=datetime.now(),
auto_now=True,
)
based on it, I created a feedback form. she worked. I created a few messages, and then delete all entries from the corresponding table in the database
then I changed the names of the fields:
class Feedback(models.Model):
username_f = models.CharField(
verbose_name=u"Имя",
max_length=100,
blank=True,
)
subject_f = models.CharField(
verbose_name=u"Тема",
max_length=100,
blank=False,
)
email_f = models.EmailField(
verbose_name=u"Email",
max_length=100,
blank=True,
)
message_f = models.TextField(
verbose_name=u'Сообщение',
max_length=50000,
blank=False,
)
date_f = models.DateTimeField(
verbose_name=u'Дата создания',
default=datetime.now(),
auto_now=True,
)
and made the following from the console:
(kinopom_env)kalinins#kalinins-Lenovo-Z580 ~/.virtualenvs/kinopom_project/kinopom $ python manage.py schemamigration --auto app_menu
the result was the following:
- Deleted field username on app_menu.Feedback
- Deleted field date on app_menu.Feedback
? The field 'Feedback.message' does not have a default specified, yet is NOT NULL.
? Since you are removing this field, you MUST specify a default
? value to use for existing rows. Would you like to:
? 1. Quit now.
? 2. Specify a one-off value to use for existing columns now
? 3. Disable the backwards migration by raising an exception; you can edit the migration to fix it later
? Please select a choice:
please help to rectify the situation and explain what is happening
South is trying to decide how to create a backwards migration - in other words, how would it roll back your change. If you're happy that you're never going to want to roll back this migration, you can just choose option 3.
If you do want to roll back, then have a look at this post - it explains how to rename a model field (in this case message to message_f).
It's normal, you should chose option 2 and enter default value, if you don't plan to use backward migrations it can be any, for example "0". If you further do backward migration, deleted fields will be created anew and they will be filled by this default values.

Categories

Resources