How to set email field in Django? - python

Hi I'm making a user model in Django but getting an error regarding email field and the unique=True also not working on the email field.
class User(models.Model):
user_name = models.CharField(max_length=50,unique=True)
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
User_email = models.EmailField(max_length=70,blank=True,unique=True)
password = models.CharField(max_length=12)
The error I am getting when I am trying to run the command "python manage.py makemigrations":
You are trying to add a non-nullable field 'first_name' to user without a default; we can't do that (the database needs something to populate existing rows).
Please select a fix:
1) Provide a one-off default now (will be set on all existing rows with a null value for this column)
2) Quit, and let me add a default in models.py
Select an option:

Basically, you already have users in your database. When you add a new field to User, there ends up being a blank spot in the database for the existing users.
However, your code is such that a blank spot is not permitted. As your code is currently, there must be a value in that spot for all users.
Your options:
1. Wipe your database
If you aren't far long in the development process, just reset your database to have no users. Then all should work properly.
2. Let it be blank/null for some users and fix it later
Add one of the following to your User_Id declaration. default='DEFAULT VALUE', blank=True or null=TrueThat will let you continue along, but then you will need to fix it later for the older users.
I will also point out that your error is not about the email (User_email)field, but rather the User_id field. Just delete that entirely. Django models already come with a built in system for managing primary keys. It is the pk.

Related

django asking to add default values

I am new to django and I am facing some problem.
This was my previous model.
class Blog(models.Model):
name = models.CharField(max_length=100)
tagline = models.TextField()
I added some data to this model.
After that I added one more field to it.
Now my model looks like this..
class Blog(models.Model):
name = models.CharField(max_length=100)
tagline = models.TextField()
age = models.IntegerField()
When I ran the command python manage.py makemigrations I got the following error which is obvious.
You are trying to add a non-nullable field 'age' to blog without a default; we can't do that (the database needs something to populate existing rows).
Please select a fix:
1) Provide a one-off default now (will be set on all existing rows with a null value for this column)
2) Quit, and let me add a default in models.py
Select an option:
I don't want to add default so I deleted the table contents by accessing db.sqlite3
But again after running python manage.py makemigrations I am getting the same error.why?
Even though you have deleted the table, any changes to your Django model will always refer to the previous migration of that model, hence it still requires you to set a default value. If you're still in development, then you could delete the migrations for that model and then makemigrations again. But, this is terrible practice and you should never do this unless you are consciously squashing your models, the better way is to do what Django is telling you and set a default. This'll help in the long run anyways with error handling.
The other answers address how to set defaults quite well.
When you add a new field (i.e., column) to a database table, that field applies to all rows in the table...the existing ones and any new ones. If the field cannot be null, then some value must be specified for all of the existing rows.
By default, IntegerField() is non-nullable. This explains why you are getting the warning. You have a few options:
You can choose a default "one-off" initial value like Django suggests. All existing rows will use this value for the new field.
Assign your own values to each existing row for the new field.
Use the blank and null arguments in your model field to allow the field to accept null values.
For the last option, you'd do this like so:
models.IntegerField(blank=True, null=True)
But that might not be the best choice depending on your use case. If nullable values don't make sense for your field, I would avoid making the field support nulls.
age = models.IntegerField(null=True)
Django models fields are null set to true by default.
The way you can solve this:
Delete the Blog table from the database.
Delete the migrations folder from the app that contains Blog model.
Remove all data from django_migrations table.
Now run makemigrations and then migrate command.
Hope this will solve your problem.
Do what Django is telling you, then you can remove the default attribute if you don't need it. But it's a good practice to keep it anyway

Model using inheritance: You are trying to add a non-nullable field 'id' to typemod without a default;

I am using model inheritance in my models.py. This is my code:
class Email(models.Model):
stuff = models.CharField(max_length=40, blank=True,
null=True, default="")
class TypeMod(Email):
pass
When I run makemigrations, I get the following message although I have set the default value for all of my fields in the Email model:
You are trying to add a non-nullable field 'id' to typemod without a
default; we can't do that (the database needs something to populate
existing rows).
Please select a fix:
1) Provide a one-off default now (will be set on all existing rows
with a null value for this column)
2) Quit, and let me add a default in models.py
What am I doing wrong?!
It doesn't necessarily have to do with vagrant. I used a native Linux machine and got the same message. My solution was to remove the existing migrations.
Well I figured it out! For anyone who has the same issue, I am using vagrant and this project is running on a vm.So the problem was that the parent model was not abstract before, so a table was made in the database for the parent model. So when I switched to abstract, the table was still there. The way I solved it was that I ran "vagrant distroy" and restarted the vm.

django model with two fields from another model

I am creating model class Car and I want to have in it two references to one foreign key.
class Car(models.Model):
owner = models.ForeignKey(User)
#and here I want to have owner email (which is already set in class User)
email = owner.email
But I don't know how to make reference to field of ForeignKey already used.
I get this error:
AttributeError: type object 'User' has no attribute 'email'
Is there any way to do it?
There are two things here... the first is to find out why you want to do this. Because maybe you shouldn't.
If you just want to access the owner's email address from a Car instance you don't need to add it as a field on the Car model, you can do:
my_car = Car.objects.get(owner=me)
my_email = my_car.owner.email
This does two seperate db queries, the first to get the Car and the second to get the owning User when you access the ForeignKey.
If you want to avoid this you can use select_related:
my_car = Car.objects.select_related().get(owner=me)
my_email = my_car.owner.email
Now it's only one query, Django knows to do a join in the underlying SQL.
But, assuming you know all this and you still really want to add the owner's email to the Car model. This is called 'denormalisation' and there can be valid performance reasons for doing it.
One problem that arises is how to keep the email address in sync between the User and Car models. If you are deliberately pursuing denormalisation in your Django app I highly recommend you consider using django-denorm. It installs triggers in the SQL db and provides a nice interface for specifying denormalised fields on your model.
You should really follow django's tutorial...
You can access the user email with car_instance.owner.email.
There is no need to add existing fields to another module. You should in principle avoid repeating data. Since the email and all relevant user info exist in the user model, then the foreign key is enough to access this data in relevance to a specific car record:
car = Car.objects.first()
email = car.owner.email
You can do the same with any field of the user model.

django: Does `unique=True` prevent `IntegrityError`?

I realized that when I have a simple model:
class Category(models.Model):
name = models.CharField(max_length=128, unique=True)
views = models.IntegerField(default=0)
likes = models.IntegerField(default=0)
the modifier unique=True has the effect that when I add a category to the database (via an HTML form) which has a name of an instance already present in the database, the application will not crash.
Instead, I get access to form.errors which I can print to the page or to the terminal.
If I omit unique=True and I try to add a category to the database with a name that already exists, I get an IntegrityError and my application crashes.
So it seems to me that defining unique=True is pretty important for the behaviour of the application. I guess then there must be other model attributes which are equally importa
In the django documentation, where can I read about this and if there are other such attributes?
First of all, you created the model using the unique constraint, so the database already has the unique constraint.Something like (for MySQL):
CONSTRAINT myapp_category UNIQUE (name)
Now, you are probably using a ModelForm, which picks this attribute unique=True, and applies that validation. So, you can catch the errors via form.errors and handle it gracefully.
When you remove the attribute, the database still has the constraint, but the ModelForm does not perform that validation for you, hence the IntegrityError
So, to answer your question - unique=True does help prevent raising of an exception when you use it in the context of a ModelForm, or you would have to handle it yourself to make it fail gracefully.
To remove the unique constraint from the database, you would have to use a migration tool like south
My guess is that you have a database model which has a UNIQUE constraint on the name column. If you try to insert two rows with the same name, then the database (via the database driver) will throw an IntegrityError. This happens completely independent of django.
django then has a model how to build forms. If you omit the unique=True, django assumes that the column in the database isn't unique and doesn't add the necessary checks in the form validation step.
So you basically have a config mismatch between your form and your database.
Solutions:
Make sure the constraints for forms and database columns are always the same
Write your own, custom validation rules (see the django documentation).
Alternatively: Write code that gets unique constraints from the database and then, when you create a form, check that the necessary attributes are set to avoid this error.

Should I delete or set a variable to "deleted" in django/postgresql?

Specifically for my app, I have created this model in order to allow a user (the user_parent) to follow other users.
class Follow(models.Model):
user_parent = models.ForeignKey(User, unique=True, related_name="follow_set")
users_followed = models.ManyToManyField(User, related_name="follow_followed")
Whenever a user parent follows another user, the user being followed is added to the variable users_followed.
Right now I am trying to figure out how best to unfollow other users. Do I delete the user being followed from the users_followed variable or should I add another field to the model describing whether the user is still being followed or not?
Which is the most expensive action for the database to perform?
It would be the same in terms of expense, since it is a table update. So either approach should be fine

Categories