Django - Can we erase migration folder? - python

I have a class like this (I didn't know about abstract class at the beginning):
class Client(models.Model):
company_name = models.CharField(max_length=50)
referrer = models.ForeignKey(User, null=True, blank=True)
address = models.CharField(max_length=400, blank=True)
class Customer(Client):
def __str__(self):
return "{company:s}".format(company=self.company_name)
I tried to add abstract class to client, did the makemigrations but migrate crash with this message:
django.core.exceptions.FieldError: Local field 'address' in class 'Customer' clashes with field of similar name from base class 'Client'
I tried to restart from scratch because I don't need migration right now and delete the folder.
I run manage.py migrate and It tells me that I didn't have auth_user table. Then I use manage.py migrate auth then manage.py migrate and it works !
Cool, almost, my django project is now running but when I launch the test I still have the issue:
can't find auth_user table...
I guess test didn't create the migrate auth for the test database.
What did I do wrong?

Related

Makemigrations and migrate in Django

I have a problem in the Django
For example:
In Definition of models. i have :
class Social_Network(models.Model):
Name = models.TextField(null=False)
Addresses = models.TextField(null=False)
And after running
python manage.py makemigrations
python manage.py migrate
Until this part everything its ok
My problem is starting now. When i want to change (Social_Network) models.
class Social_Network(models.Model):
Id = models.TextField(null=False)
Name = models.TextField(null=False)
Addresses = models.TextField(null=False)
I inserted 'Id' to 'social network' models
And after running
python manage.py makemigrations
python manage.py migrate
I encounter the following error
Please Help me
For convenience, each model has an AutoField named id by default unless you explicitly specify primary_key=True on a field in your model. See the documentation for AutoField for more details.

Limit custom migration to one model

I have decided to implement registration option for my website, I used this tutorial (signup with confirmation part). Following this material I have created Profile module to hold some info. Everything (seems to be) working now, but the problem is that old profiles throws relatedObjectDoesNotExist error. According to these two questions (first, second) I need to make a migration to create profiles for old user accounts. I tried to follow this doc as suggested in one of the answers, but then I try to run a migration I get following error: KeyError: ('stv', 'bazinekaina')
stv is the name of my app and bazinekaina is the name of the next model after the one I need to create profiles.
How to limit migration to only the first model?
My relevant models.py code:
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
email_confirmed = models.BooleanField(default=False)
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
email = models.EmailField(max_length=254)
#receiver(post_save, sender=User)
def update_user_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.get(user=instance)
instance.profile.save()
#next model, this one throws an error, despite the fact it should not be touched at all
class BazineKaina(models.Model):
#bazines kainos modelis
bazka = models.DecimalField(max_digits=5, decimal_places=2)
data = models.DateField(auto_now=False, auto_now_add=True)
def __str__(self):
return str(self.bazka)
class Meta:
verbose_name_plural = "BazinÄ— kaina"
get_latest_by = 'data'
Migration file crated after using python manage.py makemigrations --empty stv command, named 0001_initial.py:
from django.db import migrations, models
def sukurti_profilius(apps, schema_editor):
Profile = apps.get_model("stv", "Profile")
for user in Profile.objects.all():
Profile.objects.get_or_create(user=user)
class Migration(migrations.Migration):
dependencies = [
]
operations = [
]
How and what I should fix to stop migrations from applying to the unrelated models (and throwing error)?
Sorry if it is basic question, but whole django is still very new to me.
If your migration is named 0001_initial then it means that you don't have a migration that actually creates the table for the profile model.
Remove that migration and run:
python manage.py makemigrations stv
python manage.py makemigrations stv --empty --name create_profiles
Then you should have a file 0002_create_profiles.py and put the logic to create profiles there.

Django MySQL IntegrityError: ("Field 'created_at' doesn't have a default value")

I am new to Django.
IntegrityError: (1364, "Field 'created_at' doesn't have a default value")
occurred when I didn't write created_at for models I defined at models.py.
Every time I face such error, I add
created_at = models.DateTimeField(default=timezone.now, null=True)
to models.py and then run python manage.py makemigrations; python manage.py migrate --fake.
Is that OK? (I mean, does it follow Django best practice or not? )
When I was using Rails, I've never faced such issues. Why doesn't Django automatically handle created_at column?
Also, I'd like to know why --fake option removes this error.
version
Django==1.11.5
mysqlclient==1.3.12
Python 3.6.1
Thanks in advance.
It seems that you want to have an attribute created_at which is set on every creation of a model instance. There is an easier way for that:
created_at = models.DateTimeField(auto_now_add=True)
Here the docs explaining it in detail https://docs.djangoproject.com/en/1.11/ref/models/fields/#django.db.models.DateField.auto_now_add
From your comments I think I can reproduce your steps. You had a model class in your models.py:
from django.db import models
class YourModel(models.Model):
one_field = models.CharField()
another_field = models.CharField()
Then you ran:
python manage.py makemigrations
python manage.py migrate
After that you added to your model class:
from django.db import models
class YourModel(models.Model):
one_field = models.CharField()
another_field = models.CharField()
created_at = models.DateTimeField(default=timezone.now, null=True)
but forgot to run the migrations and got the error message.
This is because Django ORM is looking for the property created_at, which it can't find in the DB.
You have to run the commands:
python manage.py makemigrations
python manage.py migrate
again. Remember that the option --fake won't change the DB. It just marks the migration as run. Use it only when you're sure what are you doing.
As Johannes Reichard has suggested you should better use auto_now_add (and there is also auto_now) for this purpose. Check the official documentation.
The drawback is that this field won't be shown in the admin. A workaround is to overwrite the save method:
def save(self, *args, **kwargs):
if not self.pk:
self.created_at = timezone.now() # import it from django.utils
super(YourModel, self).save(*args, **kwargs)

How do I migrate changes in Django when I'm uninheriting a model?

If I have two models and one inherits from another and setup the database with migrate etc. like so:
class TemplateProduct(models.Model):
type = models.CharField(max_length=20)
class Product(TemplateProduct):
name = models.CharField(max_length=80)
Then how would I migrate the db to make it so that Product does not inherit from TemplateProduct? Say I just want these models instead:
class TemplateProduct(models.Model):
type = models.CharField(max_length=20)
class Product(models.Model):
name = models.CharField(max_length=80)
When I try to migrate this, I get the following error:
django.db.utils.ProgrammingError: column "templateproduct_ptr_id" of relation "product_product" does not exist
And then when I remove the delete "templateproduct_ptr_id" from the migration, I get the following error:
django.core.exceptions.FieldError: Local field u'id' in class 'Product' clashes with field of similar name from base class 'TemplateProduct'
As the title says: how do I migrate changes in Django when I'm uninheriting a model?
So my solution was to delete both models. Then python manage.py makemigrations --merge, then I added the models back the way I wanted them, finally running python manage.py makemigrations --merge again to add the models back in.
This may not be the most elegant solution but it worked.

Django two models share a table, run the unit test, then syncdb will report exception:table already exists

class A(models.Model):
name = models.CharField(max_length=100)
class Meta:
db_table = "some_table"
class B(models.Model):
title = models.CharField(max_length=100, db_column="name")
class Meta:
db_table = "some_table"
we get two models sharing a table, and we create the database schema manually via a customized command named ./manage.py db.
but for unit test, when running ./manage.py test,
an error occurs: "Table 'some_table' already exists".
how to avoid running ./manage.py syncdb and execute the manual command?

Categories