I would like to understand what I'm missing.
My model before cahnge:
class sectorToMapXY(models.Model):
pos = models.IntegerField()
name = models.CharField(max_length=15)
mapX = models.FloatField(default=0)
mapY = models.FloatField(default=0)
destMap = models.ForeignKey(Document, related_name='%(class)s_docfile')
Model after change (updated the on_delete delete in the destMap):
class sectorToMapXY(models.Model):
pos = models.IntegerField()
name = models.CharField(max_length=15)
mapX = models.FloatField(default=0)
mapY = models.FloatField(default=0)
destMap = models.ForeignKey(Document, related_name='%(class)s_docfile',on_delete=models.SET(-1))
When running python manage.py makemigrations it return No changes detected.
When changing the on_delete to SET_NULL or SET_DEFAULT it does detect the change.
Update:
I haven't set the SET_NULL nor SET_DEFAULT so when trying to run it returns error (but it detects the change):
SystemCheckError: System check identified some issues:
ERRORS:
dashboard.sectorToMapXY.destMap: (fields.E321) Field specifies on_delete=SET_DEFAULT, but has no default value.
HINT: Set a default value, or change the on_delete rule.
When adding the models.ForeignKey(Document, related_name='%(class)s_docfile',null=True,on_delete=models.SET_NULL)
running python manage.py makemigrations returns to No changes detected.
I wasn't able to reproduce your error on django 1.8.
However, I'm not sure how did the makemigrations command worked successfully when setting on_delete=SET_NULL or on_delete=SET_DEFAULT, since you are missing null=True or default=default_value on the field definition.
If this is the first time you handle migrations on your app, you should run:
$ python manage.py makemigrations your_app_label
As specified here.
Related
After experimenting with setting up CustomUser and many-to-many relationships, I decided to make some (what turned out to be major) changes to the models. I had read that CustomUser/Auth needs to be set up first, or else it'll be a mess. But since I'm just learning and there was barely any data involved, I just went for it--not to mess up the CustomUser model intentionally, but I changed a model name--and (maybe this is the critical error) I updated the names everywhere it appeared. Now I'd deleted and reset the database, VENV folder, all the migration (along with __pycache__) files, and recreated test data so many times that I thought I could download the GitHub repo and set up a fresh new app easily again. But the app refuses to run and keeps asking for a missing table.
Re-creating the app isn't my main concern-I'd like to understand what happened-what is this missing table (see the snippet of the error code)? AND: Why is a perfectly intact repo having the same issue with the missing table?
Exception in thread django-main-thread:
Traceback (most recent call last):
File "/Volumes/Volume2/dev/lms6-v2/venv/lib/python3.9/site-packages/django/db/backends/utils.py", line 89, in _execute
return self.cursor.execute(sql, params)
File "/Volumes/Volume2/dev/lms6-v2/venv/lib/python3.9/site-packages/django/db/backends/sqlite3/base.py", line 477, in execute
return Database.Cursor.execute(self, query, params)
sqlite3.OperationalError: no such table: accounts_staff
The app is called accounts and the CustomUser models are:
class CustomUser(AbstractUser):
user_type_data = ((1, "HOD"), (2, "Staff"), (3, "Student"))
user_type = models.PositiveSmallIntegerField(default=1, choices=user_type_data)
email = models.EmailField(_('email address'), unique=True)
is_staff = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
date_joined = models.DateTimeField(default=timezone.now)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = []
objects = CustomUserManager()
def __str__(self):
return self.email
class AdminHOD(models.Model):
id = models.AutoField(primary_key=True)
admin = models.OneToOneField(CustomUser, on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now_add=True)
objects = models.Manager()
class Staff(models.Model):
id = models.AutoField(primary_key=True)
admin = models.OneToOneField(CustomUser, on_delete=models.CASCADE)
user_type = "Staff"
email = models.EmailField()
address = models.TextField(blank=True)
date_joined = models.DateTimeField(auto_now_add=True)
note = models.TextField(blank=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now_add=True)
objects = models.Manager()
def __str__(self):
return self.admin.first_name + " " + self.admin.last_name
def get_absolute_url(self):
return reverse('staff_detail', kwargs={'pk': self.pk})
first of all u need to delete all your migrations files(sure u have ) and the (pycache) ...
After you have done that dont just run makemigration u have to be logical with it
run python manage.py makemigrations <app_name:the app that contains the AUTH_USER_MODEL>
run python manage.py makemigrations <app_name> but this time u decide what app comes next in the way u wrote ur models they makemigrations in that order'
3)run python manage.py makemigrations
4)lastly run python manage.py migrations
... this how i solved this issue anytime i run into this problems
Obviously messing with the CustomUser model in Django isn't to be attempted casually, but this was a good learning experience. So for the newly initiated accidentally stuck at the same spot, the answer by Ogechuwku Matthew is a good start.
To elaborate-this is what I did:
Deleted all the migration files, including files in __pycache__ (EXCEPT for the __init__ file(s).
Disabled the AUTH_USER_MODEL = 'myapp.MyCustomUser' line in settings.py This step is key.
Removed (or commented out) all but the most essential files.
Commented out all but the CustomUser model and models extended from it.
Ran python manage.py makemigrations <app_name> and then 'python manage.py migrate`
After step 4 worked, ran python manage.py makemigrations <app_name> and python manage.py migrate again.
Moved the rest of the files back in, starting with the simplest bits, like 'HomeView' in views.py and 'home.html'.
When the app started up with 'home.html', un-commented models, views, and urls one cluster at a time.
Additionally: If error occur when running the app, first check the embedded dynamic links--they may extend or include files that aren't there yet-same with {% load static %}
I am writing a apps and run makemigrations and migrate multiple time when i add new field.
And now i have added a new foreignKey Field in models and then i run the command:
python3 manage.py makemigrations
after this, i run this command python3 manage.py migrate but it throws me following error
TypeError: an integer is required (got type str)
and later again i run this command pythion3 manage.py migrate --fake and i have successfully migrated and got another problem, when i go to django admin templates and click on my models to add data, it throws me this error:
OperationalError at /admin/booking/seats/
no such column: booking_seats.seat_for_id
I am not getting whats wrong with it, can anyone help me to fix this?
for your reference, see my models:
class Seats(models.Model):
alias = models.UUIDField(
primary_key=True,
default=uuid4,
editable=False
)
seat_no = models.IntegerField(
choices=SeatChoices.choices(),
)
availability = models.IntegerField(
choices=SeatAvailability.choices(),
default=SeatAvailability.AVAILABLE
)
seat_for = models.ForeignKey('booking.show', on_delete=models.CASCADE)
def __str__(self):
return str(self.seat_no)
class Show(models.Model):
alias = models.UUIDField(
primary_key=True,
default=uuid4,
editable=False
)
show_schedule = models.IntegerField(
choices=ShowSchedule.choices(),
)
movie = models.CharField(max_length=50)
def __str__(self):
return str(self.show_schedule)
I just added this new field seat_for = models.ForeignKey('booking.show', on_delete=models.CASCADE) then i facing the problem
Can anyone help me in this case?
I think the problem is that your model is not with a capital, as Python is case sensitive. It should be like this:
seat_for = models.ForeignKey('booking.Show', on_delete=models.CASCADE)
I have created a Django web application that has models and many instances of models created. The problem is that I want to add another field to one of the models already in use (has over 1000 instances). I have had difficult experiences with Django Migrations in the past and am scared that if I modify the model by adding the field, my web application will not function.
How do I change the model in such a way that it will not affect the functionality of my web application?
the following should solve your problem without introducing any issues.
You can check that the data has been populated correctly by checking the fields in django admin if need be.
I would suggest, however, that you set yourself up with a dev environment so that you can test this kind of thing without worrying about whether it's going to cause issues on your production environment.
I hope this helps!
Initial:
Models.py
class ExampleModel(models.Model):
name = models.CharField(blank=True, null=True)
First change:
Models.py
class ExampleModel(models.Model):
name = models.CharField(blank=True, null=True)
unique_str = models.CharField(blank=True, null=True) # add this here
Run:
python manage.py makemigrations
python manage.py migrate
Then you can run a script to populate your unique_str:
# get all model instances
example_models = ExampleModel.objects.all()
# update each unique_str as required
for e in example_models:
e.unique_str = e.pk # add any required logic here to assign value to this variable
e.save()
Finally:
Models.py
class ExampleModel(models.Model):
name = models.CharField(blank=True, null=True)
unique_str = models.CharField(blank=True, null=True, unique=True) # add unique
and then again, Run:
python manage.py makemigrations
python manage.py migrate
I have 2 model-classes inside models.py file :
class Certificate(models.Model):
comments = models.TextField(blank=True, default='')
generic_certificate = models.ForeignKey(GenericCertificate, related_name='certificates_awarded')
tag = models.ForeignKey('Tag', related_name='certificates_awarded', null=True, blank=True)
class GenericCertificate(CommonInfo):
CERTIFICATE_TYPE = (('C', 'system created'),
('U', 'user created'))
certificate_icon = models.ImageField(upload_to='certificate/icons', default='defaults/certificate.png')
certificate_type = models.CharField(choices=CERTIFICATE_TYPE, max_length=1, default='C')
template = models.FileField(upload_to='certificate/generic_templates')
They are working fine in django admin , but When I am adding one more model class it starts giving error on hitting Generic certificates option: Included operation : South Migration and syncdb
Exception Type: ProgrammingError
Exception Value:
relation "certificates_genericcertificate" does not exist
LINE 1: SELECT COUNT(*) FROM "certificates_genericcertificate"
newly added model class in same models.py
class PositionCertificate(models.Model):
rewardee = models.CharField(max_length=50, default = '0,0')
org_logo = models.CharField(max_length=50, default = '0,0')
tag_name = models.CharField(max_length=50, default = '0,0')
How to remove this error ? and why this error is coming ?
Error
relation "certificates_genericcertificate" does not exist
means that "certificates_genericcertificate" relation do not exists in your database.
Please do
python manage.py syncdb
and if you are using South you can use
python manage.py migrate
try to hit these commands and if it does not help you, drop your tables/database and recreate tables/database by using syncdb.
I have an already existing app with alot of database entries.
class Foo(models.Model):
value = models.TextField(u"Value")
For this I do this:
python manage.py schemamigration myapp --initial
python manage.py migrate myapp
I change the model to such:
class Foo(models.Model):
value = models.TextField(u"Value")
live = models.BooleanField(u"Live", default=False)
creation_time = models.DateTimeField("Creation Time", auto_now_add=True, null=True, blank=True)
and migrate:
python manage.py schemamigration myapp --auto
python manage.py migrate myapp
I get django.db.utils.DatabaseError: relation "myapp.foo" already exists error.
I have already checked this question but --fake doesn't seem to be supported via South anymore.
Your models look invalid to me, though I'd be surprised if that's what's actually causing the problem.
It looks like your first argument is intended to be the verbose_name attribute, your model should probably look like this:
class Foo(models.Model):
value = models.TextField(verbose_name = u"Value")
live = models.BooleanField(verbose_name = u"Live", default=False)
creation_time = models.DateTimeField(verbose_name = u"Creation Time", auto_now_add=True, null=True, blank=True)
(you also forgot the u before the verbose_name for creation_time).
Meanwhile, --fake is definitely still supported (see the docs), what error are you getting when you try and run it?