Django, makemigrations doesn't detect model changes - python

I am learning Django and I am using this tutorial:
https://www.youtube.com/watch?v=F5mRW0jo-U4&t=912s
I created an app called products and I have it in INSTALLED_APPS.
Upon creating a Product class in the models.py file in the products app folder, I created some fields such as price.
However, when I tried to use the makemigrations command, no changes detected was reported.
Folder Layout and Settings
models.py
from django.db import models
# Create your models here.
class Product(models.Model):
title = models.TextField()
description = models.TextField()
price = models.TextField()
I checked if there were any issues with the Product class but there doesn't seem to be any as far as I can see, so I am at a loss as to why no changes were detected.

15
You may have deleted the migrations folder inside the app or init.py inside the /migrations/ folder, create a new one
myproject/ apps/
myapp/
migrations/
init.py
You can always do makemigrations seperately without doing the above step
python manage.py makemigrations myapp

Refer the table - djangomigrations .. if the entry is there for the makemigration file already in the table then trunckage and rerun makemigrations and then do migrate

Related

django table onlineshop_product has no column named name

I work on an online shopping website project with the help of Django. and I'm a beginner in Django The following code provides a table of my database. It helps to add a product.
class Product(models.Model):
category = models.ForeignKey(Category,related_name='products', on_delete=models.CASCADE)
name = models.CharField(max_length=200,db_index=True)
slug = models.SlugField(max_length=200,db_index=True)
image = models.ImageField(upload_to='products/%y/%m/%d',blank=True)
description = models.TextField(blank=True)
price = models.DecimalField(max_digits=10, decimal_places=2)
available = models.BooleanField(default=True)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
Shows me an error in the browser. This error shows me when I add a product inside the admin panel. It helps to add a product but when I add the product the following error occurs.
OperationalError at /admin/onlineshop/product/add/
table onlineshop_product has no column named name
When I did migration using the command:
python manage.py migrate
It shows:
Operations to perform: Apply all migrations: admin, auth,
contenttypes, onlineshop, sessions Running migrations: No migrations
to apply. Your models in app(s): 'onlineshop' have changes that are
not yet reflected in a migration, and so won't be applied. Run
'manage.py makemigrations' to make new migrations, and then re-run
'manage.py migrate' to apply them.
python manage.py makemigrations
It is impossible to add the field 'created' with 'auto_now_add=True'
to product without providing a default. This is because the database
needs something to populate existing rows.
Provide a one-off default now which will be set on all existing
rows
Quit and manually define a default value in models.py. Select
an option:
How to solve it?
It is well-known issue, refer here[django-doc] for this, it will be easy if you choose 1st option.
Choose 1st option:
Then, you will be shown something like this in your shell:
Select an option: 1
Please enter the default value now, as valid Python
You can accept the default 'timezone.now' by pressing 'Enter' or you can provide another value.
The datetime and django.utils.timezone modules are available, so you can do e.g. timezone.now
Type 'exit' to exit this prompt
[default: timezone.now] >>>
Here, simply press Enter the field will be added to migration and your work is done then simply run migrate command. You can also check it in migration file.
Migration file
operations = [
migrations.AddField(
....
field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now),
)
]
Edit:
Try this:
name = models.CharField(max_length=200,db_index=True,default='any_name')
Then run makemigrations and migrate.
Change your Product(...) class like this:
from django.db import models
from datetime import datetime
class Product(models.Model):
# ... all other fields
name = models.CharField(max_length=200, db_index=True, default='Name not provided')
created = models.DateTimeField(auto_now_add=True, null=True)
updated = models.DateTimeField(auto_now=True, null=True)
and run these commands in sequence:
python manage.py makemigrations your_app_name # app name is optional parameter if you have app then provide app name
python manage.py migrate
Although settings null = True is bad idea but this will solve your problem for now but if you want to fix this issue you can follow this post or this answer.
Update
If above solution is not working or facing some issue then do like this:
Note : In this approach you've to delete you database (sqlite).
Step - 1
Delete __pycache__ & migrations folders from all of your apps
Step - 2
Delete db.sqlite3
Step - 3
Run makemigrations & migrate commands as mentioned above.

ForeignKey to 'self' in sub-application throws error on makemigrations in Django project

I'm currently working on an large Django project (version 1.10.7) and am running into an error with a model field in a sub-application. Here's what the basic structure looks like:
project/
app_one/
__init__.py
apps.py
models.py
urls.py
views.py
app_two/
__init__.py
apps.py
models.py
urls.py
views.py
The model and field in question looks like this (project/app_one/app_two/models.py):
class SampleModel(model.Model):
parent = models.ForeignKey('self', null=True, blank=True, related_name='members')
When I run python manage.py makemigrations app_one.app_two in the root folder I get this error message:
File .../django/db/models/utils.py", line 23, in make_model_tuple
"must be of the form 'app_label.ModelName'." % model ValueError: Invalid model reference 'app_one.app_two.SampleModel'. String model
references must be of the form 'app_label.ModelName'.
Here is code from other files that are relevant:
project/settings.py:
INSTALLED_APPS = filter(None, (
...
'app_one',
'app_one.app_two',
...
)
project/app_one/app_two/apps.py:
from __future__ import unicode_literals
from django.apps import AppConfig
class AppOneAppTwoConfig(AppConfig):
name = 'app_one.app_two'
label = 'app_one.app_two'
project/app_one/app_two/__init__.py:
default_app_config = 'app_one.app_two.apps.AppOneAppTwoConfig'
I believe the error here is that Django is only looking for one . in the full model name (app_one.app_two.SampleModel) to separate the app label from the model name in django/db/models/utils.py, and since there are two in this case, it fails.
My question is: This seems like a weird for Django not to account for...is there anyway to retain the dot notation of the app label and still have a self-referencing ForeignKey in a sub-application?
As you mention, it seems to be a lookup error when the project is trying to locate your app due to the nested apps. This can be solved by specifying the app name with an app_label in the models internal meta class:
class SampleModel(models.Model):
...
class Meta:
app_label = 'app_two'
I was able to solve this by changing the app_label to 'app_one_app_two' in apps.py. Because django references this when registering the related models, it doesn't break. All migrations are then registered under that label as well.

OperationalError:no such table:article_article

learning django recently and ran into a problem with Django.
This is my models.py:
# -*- coding:utf-8 -*-
#/usr/bin/env python
from django.db import models
# Create your models here.
class Article(models.Model):
title = models.CharField(max_length = 100)
category = models.CharField(max_length=50,blank=True)
date_time = models.DateTimeField(auto_now_add=True)
content = models.TextField(blank=True,null=True)
def __unicode__(self):
return self.title
class Meta:
ordering = ['date_time']
first I input these in cmd:
python manage.py migrate
python manage.py makemigrations
python manage.py migrate
but when, in the Django shell, I input this code:
from article.models import Article
Article.objects.create(title = 'Hello World', category = 'Python', content = 'what')
I received this error message:
OperationalErrors:no such table:article_ article
what's wrong?
thanks for your help
MAYBE something on migrations is not correct...
To create an app:
1) python manage.py migrate
2) python manage.py startapp myapp
3) add 'myapp', to INSTALLED_APPS in settings.py
4) create your model and save
5) python manage.py makemigrations myapp
6) python manage.py migrate myapp
You have to do the last two steps every time you change something in models.py.
Now some links: 1 2 and a very useful tutorial Django Girls
You can simply erase you db by deleting your db.sqlite
then ./manage.py syncdb.
If you don't want to loose your data then you need first, after making syncdb, run ./manage.py makemigrations, ./manage.py migrate.
Than, after changing your models you run ./manage.py makemigrations and ./manage.py migrate -these command will make necessary changes to DB schema.

django python manage py syncdb doesn't add tables to mysql

I just started learning Django yesterday, and I'm having a problem when I trying to add new tables to my MySQL server:
I created a model in models.py (lets say the app name is "article" and the model name is "Article"). I ran syncdb lots of times with different examples in the INSTALLED_APPS in the settings.py (like "article" and "article.models") but it doesn't add the tables.
(Of course I see the other tables like "auth_group", "auth_group_permissions" etc.. but not the table of the Article model I created.)
model.py:
from django.db import models
class Article(models.Model):
title = models.CharField(max_length=200)
body = models.TextField()
pub_date = models.DateTimeField('date publish')
likes = models.IntegerField()
the project structure:
python version: 2.7.9
the db:
The documentation for the new Django migrations is available here:
https://docs.djangoproject.com/en/dev/topics/migrations/
once you have your new app and added it to INSTALLED_APPS in settings.py, you do the following:
python manage.py makemigrations
this will create a python file in the app migrations folder. It will realize the changes, new additions...etc to apply to your database and then you run
python manage.py migrate
no more syncdb, it will be obsolete soon

Split models.py into several files

I'm trying to split the models.py of my app into several files:
My first guess was do this:
myproject/
settings.py
manage.py
urls.py
__init__.py
app1/
views.py
__init__.py
models/
__init__.py
model1.py
model2.py
app2/
views.py
__init__.py
models/
__init__.py
model3.py
model4.py
This doesn't work, then i found this, but in this solution i still have a problem, when i run python manage.py sqlall app1 I got something like:
BEGIN;
CREATE TABLE "product_product" (
"id" serial NOT NULL PRIMARY KEY,
"store_id" integer NOT NULL
)
;
-- The following references should be added but depend on non-existent tables:
-- ALTER TABLE "product_product" ADD CONSTRAINT "store_id_refs_id_3e117eef" FOREIGN KEY ("store_id") REFERENCES "store_store" ("id") DEFERRABLE INITIALLY DEFERRED;
CREATE INDEX "product_product_store_id" ON "product_product" ("store_id");
COMMIT;
I'm not pretty sure about this, but i'm worried aboout the part The following references should be added but depend on non-existent tables:
This is my model1.py file:
from django.db import models
class Store(models.Model):
class Meta:
app_label = "store"
This is my model3.py file:
from django.db import models
from store.models import Store
class Product(models.Model):
store = models.ForeignKey(Store)
class Meta:
app_label = "product"
And apparently works but i got the comment in alter table and if I try this, same thing happens:
class Product(models.Model):
store = models.ForeignKey('store.Store')
class Meta:
app_label = "product"
So, should I run the alter for references manually? this may bring me problems with south?
For anyone on Django 1.9, it is now supported by the framework without defining the class meta data.
https://docs.djangoproject.com/en/1.9/topics/db/models/#organizing-models-in-a-package
NOTE: For Django 2, it's still the same
The manage.py startapp command creates an application structure that includes a models.py file. If you have many models, organizing them in separate files may be useful.
To do so, create a models package. Remove models.py and create a myapp/models/ directory with an __init__.py file and the files to store your models. You must import the models in the __init__.py file.
So, in your case, for a structure like
app1/
views.py
__init__.py
models/
__init__.py
model1.py
model2.py
app2/
views.py
__init__.py
models/
__init__.py
model3.py
model4.py
You only need to do
#myproject/app1/models/__init__.py:
from .model1 import Model1
from .model2 import Model2
#myproject/app2/models/__init__.py:
from .model3 import Model3
from .model4 import Model4
A note against importing all the classes:
Explicitly importing each model rather than using from .models import * has the advantages of not cluttering the namespace, making code more readable, and keeping code analysis tools useful.
I'd do the following:
myproject/
...
app1/
views.py
__init__.py
models.py
submodels/
__init__.py
model1.py
model2.py
app2/
views.py
__init__.py
models.py
submodels/
__init__.py
model3.py
model4.py
Then
#myproject/app1/models.py:
from submodels/model1.py import *
from submodels/model2.py import *
#myproject/app2/models.py:
from submodels/model3.py import *
from submodels/model4.py import *
But, if you don't have a good reason, put model1 and model2 directly in app1/models.py and model3 and model4 in app2/models.py
---second part---
This is app1/submodels/model1.py file:
from django.db import models
class Store(models.Model):
class Meta:
app_label = "store"
Thus correct your model3.py file:
from django.db import models
from app1.models import Store
class Product(models.Model):
store = models.ForeignKey(Store)
class Meta:
app_label = "product"
Edited, in case this comes up again for someone:
Check out django-schedule for an example of a project that does just this.
https://github.com/thauber/django-schedule/tree/master/schedule/models
https://github.com/thauber/django-schedule/
I've actually come across a tutorial for exactly what you're asking about, you can view it here:
https://web.archive.org/web/20190331105757/http://paltman.com/breaking-apart-models-in-django/
One key point that's probably relevant - you may want to use the db_table field on the Meta class to point the relocated classes back at their own table.
I can confirm this approach is working in Django 1.3
The relevant link for Django 3 is:
https://docs.djangoproject.com/en/3.2/topics/db/models/#organizing-models-in-a-package
Links to previous versions of documentation are broken. The example there is very succinct:
To do so, create a models package. Remove models.py and create a myapp/models/ directory with an init.py file and the files to store your models. You must import the models in the init.py file.
For example, if you had organic.py and synthetic.py in the models directory:
from .organic import Person
from .synthetic import Robot
Easiest Steps :
Create model folder in your app (Folder name should be model)
Delete model.py file from app directory (Backup the file while you delete it)
And after create init.py file in model folder
And after init.py file in write simple one line
And after create model file in your model folder and model file name should be same like as class name,if class name is 'Employee' than model file name should be like 'employee.py'
And after in model file define your database table same as write like in model.py file
Save it
My Code : from django_adminlte.models.employee import Employee
For your : from app_name.models.model_file_name_only import Class_Name_which_define_in_model_file
__init__.py
from django_adminlte.models.employee import Employee
model/employee.py (employee is separate model file)
from django.db import models
class Employee(models.Model):
eid = models.CharField(max_length=20)
ename = models.CharField(max_length=20)
eemail = models.EmailField()
econtact = models.CharField(max_length=15)
class Meta:
db_table = "employee"
# app_label = 'django_adminlte'
def __str__(self):
return self.ename
I wrote a script that might be useful.
github.com/victorqribeiro/splitDjangoModels
it split the models in individual files with proper naming and importing; it also create an init file so you can import all your models at once.
let me know if this helps

Categories

Resources