No fixture named 'X' found - django

I'm using Django 1.6 and I use South to handle migrations.
In most of my application I used to have initial_data.json files. I converted them to be loaded with migrations rather than automatically by Django (as this is recommended in the documentation)
I was using version 0.8.2 of South when I ran into a weird behavior / bug where loading fixtures is done according to the model code and not the state of the migration. I saw that the newest version (0.8.4) has since added some bug fixes related to loaddata, so I upgraded to it.
Now I get the following error on all the migration that load fixtures:
UserWarning: No fixture named 'X' found.
When I use Django's loaddata it works fine. Any ideas on how to solve this?

South and fixtures
South simply patches syncdb to skip the fixture loading for models with migrations, and actually loads them after the final migration for an app has been run.
Make sure your initial_data file is located in the correct place
Loading initial_data does not require you do actually do something, but place the fixtures in the correct place as explained in Django's documentation.
To quote the docs:
By default, Django looks in the fixtures directory inside each app for
fixtures. You can set the FIXTURE_DIRS setting to a list of additional
directories where Django should look.
This means that if you have an app called "myapp", you'd create a "fixtures" dir inside it and place the json there, e.g.: myproject/myapp/fixtures.
Django 1.7 and newer
Django 1.7 introduced built-in migrations. These have an interface similar to South; management commands to create migrations makemigrations, run them migrate, and others.
However, initial_data fixtures are no longer auto-loaded on syncdb run; unless it is an existing app, and has no migrations. This is mentioned in the release notes.
The docs now recomend to create a datamigration to handle fixture loading. Luckily, this is pretty easy to do, here's how I usually do it:
1. create an empty data migration
$ python manage.py makemigrations --empty myapp
If you had only the initial migration, you end up with these files (note that I renamed migration 0002 for clarity):
myapp/
├── __init__.py
├── fixtures
│   └── my_initial_data.json
└── migrations
   ├── 0001_initial.py
   ├── 0002_load_fixture.py
└── __init__.py
2. update the code of 0002_load_fixture.py to run loaddata
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations
from django.core.management import call_command
def load_my_initial_data(apps, schema_editor):
call_command("loaddata", "my_initial_data.json")
class Migration(migrations.Migration):
dependencies = [
('myapp', '0001_initial'),
]
operations = [
migrations.RunPython(load_my_initial_data),
]

This error also occurs when the filename does not include the '.json' extension.
In order to load a fixture from current working directory it has to end with '.json'.

Why don't you run loaddata comand from your migration then?
import datetime
from south.db import db
from south.v2 import DataMigration
from django.db import models
class Migration(DataMigration):
def forwards(self, orm):
from django.core.management import call_command
call_command("loaddata", "my_fixture.json")

If your still getting the error:
No fixture named 'X' found
Try using the path to the json file, as manage.py is probably not being run from the project directory (it may even be run from the root directory). Try something like this:
import os
app_path = os.path.dirname(os.path.dirname(os.path.realpath(__file__))
json_path = os.path.join(app_path, 'fixtures', 'my_fixture.json')
call_command("loaddata", json_path)

Related

django makemigrations doesn't recognize new model [duplicate]

I was trying to create migrations within an existing app using the makemigrations command but it outputs "No changes detected".
Usually I create new apps using the startapp command but did not use it for this app when I created it.
After debugging, I found that it is not creating migration because the migrations package/folder is missing from an app.
Would it be better if it creates the folder if it is not there or am I missing something?
To create initial migrations for an app, run makemigrations and specify the app name. The migrations folder will be created.
./manage.py makemigrations <myapp>
Your app must be included in INSTALLED_APPS first (inside settings.py).
My problem (and so solution) was yet different from those described above.
I wasn't using models.py file, but created a models directory and created the my_model.py file there, where I put my model. Django couldn't find my model so it wrote that there are no migrations to apply.
My solution was: in the my_app/models/__init__.py file I added this line:
from .my_model import MyModel
There are multiple possible reasons for django not detecting what to migrate during the makemigrations command.
migration folder You need a migrations package in your app.
INSTALLED_APPS You need your app to be specified in the INSTALLED_APPS .dict
Verbosity start by running makemigrations -v 3 for verbosity. This might shed some light on the problem.
Full path In INSTALLED_APPS it is recommended to specify the full module app config path 'apply.apps.MyAppConfig'
--settings you might want to make sure the correct settings file is set: manage.py makemigrations --settings mysite.settings
specify app name explicitly put the app name in manage.py makemigrations myapp - that narrows down the migrations for the app alone and helps you isolate the problem.
model meta check you have the right app_label in your model meta
Debug django debug django core script. makemigrations command is pretty much straight forward. Here's how to do it in pycharm. change your script definition accordingly (ex: makemigrations --traceback myapp)
Multiple databases:
Db Router when working with django db router, the router class (your custom router class) needs to implement the allow_syncdb method.
makemigrations always creates migrations for model changes, but if
allow_migrate() returns False,
I've read many answers to this question often stating to simply run makemigrations in some other ways. But to me, the problem was in the Meta subclass of models.
I have an app config that says label = <app name> (in the apps.py file, beside models.py, views.py etc). If by any chance your meta class doesn't have the same label as the app label (for instance because you are splitting one too big app into multiple ones), no changes are detected (and no helpful error message whatsoever). So in my model class I have now:
class ModelClassName(models.Model):
class Meta:
app_label = '<app name>' # <-- this label was wrong before.
field_name = models.FloatField()
...
Running Django 1.10 here.
Another thing that will cause this is a trailing comma after the field which will cause the field to skipped during makemigrations:
class MyModel(models.Model):
name = models.CharField(max_length=64, null=True) # works
language_code = models.CharField(max_length=2, default='en') # works
is_dumb = models.BooleanField(default=False), # doesn't work
I had a trailing , in one line perhaps from copy&paste. The line with is_dumb doesn't create a model migration with ./manage.py makemigrations because Python thinks it is a tuple, and Django doesn't consider it a field.
It is a comment but should probably be an answer.
Make sure that your app name is in settings.py INSTALLED_APPS otherwise no matter what you do it will not run the migrations.
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'blog',
]
Then run:
./manage.py makemigrations blog
update: One should make sure that an __init__.py file exists in the migrations folder before trying:
./manage.py makemigrations <myapp1> <myapp2> ... <myappN>
There are sometimes when ./manage.py makemigrations is superior to ./manage.py makemigrations <myapp> because it can handle certain conflicts between apps.
Those occasions occur silently and it takes several hours of swearing to understand the real meaning of the dreaded No changes detected message.
Therefore, it is a far better choice to make use of the following command:
./manage.py makemigrations <myapp1> <myapp2> ... <myappN>
Method : 1
Step : 1
Make sure your app must be included in INSTALLED_APPS in settings.py
Stpe : 2
python manage.py makemigrations <appname>
if same message shows (No changes detected)
!Warning This is Very Risky For Your Project So Make Sure You Have Backup For Your Project Before Applying The Method 2.
Method 2
rename your app name and make new app using :
django-admin startapp <appname>
copy all .py files except from the old app
migration folder
pycache folder
init.py
test.py file if you didn't wrote code in it
and paste into the new app which you made recently
remember you have to make exact the same name for new app otherwise you have to make more changes in the project.
Make sure your app is mentioned in installed_apps in settings.py
Make sure you model class extends models.Model
My problem was much simpler than the above answers and probably a far more common reason as long as your project is already set up and working. In one of my applications that had been working for a long time, migrations seemed wonky, so in a hurry, I did the following:
rm -r */migrations/*
rm db.sqlite3
python3 manage.py makemigrations
No changes detected
Whaat??
I had mistakenly also removed all the __init__.py files :( - Everything was working again after I went in and:
touch ads1/migrations/__init__.py
For each of my applications then the makemigrations worked again.
It turns out that I had manually created a new application by copying another and forgot to put the __init__.py in the migrations folder and that confinved me that everything was wonky - leading my making it worse with an rm -r as described above.
Hope this helps someone from swearing at the "No changes detected" error for a few hours.
I had copied a table in from outside of django and the Meta class defaulted to "managed = false". For example:
class Rssemailsubscription(models.Model):
id = models.CharField(primary_key=True, max_length=36)
...
area = models.FloatField('Area (Sq. KM)', null=True)
class Meta:
managed = False
db_table = 'RSSEmailSubscription'
By changing managed to True, makemigrations started picking up changes.
Another possible reason is if you had some models defined in another file (not in a package) and haven't referenced that anywhere else.
For me, simply adding from .graph_model import * to admin.py (where graph_model.py was the new file) fixed the problem.
When adding new models to the django api application and running the python manage.py makemigrations the tool did not detect any new models.
The strange thing was that the old models did got picked by makemigrations, but this was because they were referenced in the urlpatterns chain and the tool somehow detected them. So keep an eye on that behavior.
The problem was because the directory structure corresponding to the models package had subpackages and all the __init__.py files were empty. They must explicitly import all the required classes in each subfolder and in the models __init__.py for Django to pick them up with the makemigrations tool.
models
├── __init__.py <--- empty
├── patient
│ ├── __init__.py <--- empty
│ ├── breed.py
│ └── ...
├── timeline
│ ├── __init__.py <-- empty
│ ├── event.py
│ └── ...
This might hopefully help someone else, as I ended up spending hours trying to chase this down.
If you have a function within your model by the same name, this will remove the value. Pretty obvious in hindsight, but nonetheless.
So, if you have something like this:
class Foobar(models.Model):
[...]
something = models.BooleanField(default=False)
[...]
def something(self):
return [some logic]
In that case, the function will override the setting above, making it "invisible" to makemigrations.
A very dumb issue you can have as well is to define two class Meta in your model. In that case, any change to the first one won't be applied when running makemigrations.
class Product(models.Model):
somefield = models.CharField(max_length=255)
someotherfield = models.CharField(max_length=255)
class Meta:
indexes = [models.Index(fields=["somefield"], name="somefield_idx")]
def somefunc(self):
pass
# Many lines...
class Meta:
indexes = [models.Index(fields=["someotherfield"], name="someotherfield_idx")]
In my case i forgot to insert the class arguments
Wrong:
class AccountInformation():
Correct
class AccountInformation(models.Model):
I had a different issue while creating a new app called deals. I wanted to separate the models inside that app so I had 2 model files named deals.py and dealers.py.
When running python manage.py makemigrations I got: No changes detected.
I went ahead and inside the __init__.py which lives on the same directory where my model files lived (deals and dealer) I did
from .deals import *
from .dealers import *
And then the makemigrations command worked.
Turns out that if you are not importing the models anywhere OR your models file name isn't models.py then the models wont be detected.
Another issue that happened to me is the way I wrote the app in settings.py:
I had:
apps.deals
It should've been including the root project folder:
cars.apps.deals
I solved that problem by doing this:
Erase the "db.sqlite3" file. The issue here is that your current data base will be erased, so you will have to remake it again.
Inside the migrations folder of your edited app, erase the last updated file. Remember that the first created file is: "0001_initial.py". For example: I made a new class and register it by the "makemigrations" and "migrate" procedure, now a new file called "0002_auto_etc.py" was created; erase it.
Go to the "pycache" folder (inside the migrations folder) and erase the file "0002_auto_etc.pyc".
Finally, go to the console and use "python manage.py makemigrations" and "python manage.py migrate".
I know this is an old question but I fought with this same issue all day and my solution was a simple one.
I had my directory structure something along the lines of...
apps/
app/
__init__.py
app_sub1/
__init__.py
models.py
app_sub2/
__init__.py
models.py
app_sub3/
__init__.py
models.py
app2/
__init__.py
app2_sub1/
__init__.py
models.py
app2_sub2/
__init__.py
models.py
app2_sub3/
__init__.py
models.py
main_app/
__init__.py
models.py
And since all the other models up until the one I had a problem with were being imported somewhere else that ended up importing from main_app which was registered in the INSTALLED_APPS, I just got lucky that they all worked.
But since I only added each app to INSTALLED_APPS and not the app_sub* when I finally added a new models file that wasn't imported ANYWHERE else, Django totally ignored it.
My fix was adding a models.py file to the base directory of each app like this...
apps/
app/
__init__.py
models.py <<<<<<<<<<--------------------------
app_sub1/
__init__.py
models.py
app_sub2/
__init__.py
models.py
app_sub3/
__init__.py
models.py
app2/
__init__.py
models.py <<<<<<<<<<--------------------------
app2_sub1/
__init__.py
models.py
app2_sub2/
__init__.py
models.py
app2_sub3/
__init__.py
models.py
main_app/
__init__.py
models.py
and then add from apps.app.app_sub1 import * and so on to each of the app level models.py files.
Bleh... this took me SO long to figure out and I couldn't find the solution anywhere... I even went to page 2 of the google results.
Hope this helps someone!
I forgot to put correct arguments:
class LineInOffice(models.Model): # here
addressOfOffice = models.CharField("Корхоная жош",max_length= 200) #and here
...
in models.py
and then it started to drop that annoying
No changes detected in app 'myApp '
INSTALLED_APPS = [
'blog.apps.BlogConfig',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
make sure 'blog.apps.BlogConfig', (this is included in your settings.py in order to make your app migrations)
then run python3 manage.py makemigrations blog or your app name
This could be done by using two steps that are mentioned below.
add your app to settings.py > INSTALLED_APPS
open admin.py
from .models import upImg
# Register your models here.
admin.site.register(upImg)
NOTE: replace upImg with your className defined in models.py
after that see if there still any python manage.py makemigrations are left or not. if there is, than execute python manage.py migrate too.
For more info follow this django tutorial.
The solution is you have to include your app in INSTALLED_APPS.
I missed it and I found this same issue.
after specifying my app name migration became successful
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'boards',
]
please note I mentioned boards in last, which is my app name.
One more edge case and solution:
I added a boolean field, and at the same time added an #property referencing it, with the same name (doh). Commented the property and migration sees and adds the new field. Renamed the property and all is good.
Try registering your model in admin.py, here's an example:-
admin.site.register(YourModelHere)
You can do the following things:-
1. admin.site.register(YourModelHere) # In admin.py
2. Reload the page and try again
3. Hit CTRL-S and save
4. There might be an error, specially check models.py and admin.py
5. Or, at the end of it all just restart the server
I had a similar issue with django 3.0, according migrations section in the official documentation, running this was enough to update my table structure:
python manage.py makemigrations
python manage.py migrate
But the output was always the same: 'no change detected' about my models after I executed 'makemigrations' script.
I had a syntax error on models.py at the model I wanted to update on db:
field_model : models.CharField(max_length=255, ...)
instead of:
field_model = models.CharField(max_length=255, ...)
Solving this stupid mistake, with those command the migration was done without problems. Maybe this helps someone.
My problem with this error, was that I had included:
class Meta:
abstract = True
Inside model that I wanted to creation migrate for.
Its easy, you need to add empty init.py in empty migrations folder.
Then check migrations using "python manage.py makemigrations"
Directory structure-
Your App
migrations
init.py
You should add polls.apps.PollsConfig to INSTALLED_APPS in setting.py
The possible reason could be deletion of the existing db file and migrations folder
you can use python manage.py makemigrations <app_name> this should work. I once faced a similar problem.

Django executing tests for app not in INSTALLED_APPS

Under my Django project there are a few apps and all of them have unit tests. One of them that I'm working right now is supposed to be included only in dev/stage environments, so I'm enabling it using a environment variable.
When this variable is present it is added to INSTALLED_APPS and it is working just fine, the problem is that Django is executing the tests for this app even when it is not in INSTALLED_APPS, and it fails with the following message:
ImportError: Failed to import test module: debug.tests.unit.test_services`
...(traceback information)...
RuntimeError: Model class debug.models.Email doesn't declare an explicit app_label and isn't in an application in INSTALLED_APPS.
When I define the app_label in the class Meta of models in this app the error is different, it says it can't find a table, I assume that this is because the app is not in INSTALLED_APPS, so it's migrations are not executed.
OperationalError: no such table: debug_email
I'm not sure why Django executes the tests for all apps, but not it's migrations.
Am I missing something from Django configuration for tests?
https://docs.python.org/3/library/unittest.html#unittest.TestLoader.discover says:
If load_tests exists then discovery does not recurse into the package, load_tests is responsible for loading all tests in the package.
So in the lowest __init__.py in your app which you don't always want run:
from django.apps import apps
def load_tests(loader, tests, pattern):
from django.conf import settings
if apps.is_installed("your_dev_app"):
# Actually load the tests - thanks to #barney-szabolcs
return loader.discover(start_dir=dirname(abspath(__file__)), pattern=pattern)
You need to return the discovered tests in load_tests.
So, adding to #DaveLawrence's answer, the complete code is:
# your_dev_app/__init__.py
from django.apps import apps
from os.path import dirname, abspath
def load_tests(loader, tests, pattern):
"""
loads tests for your_dev_app if it is installed.
"""
from django.conf import settings
if apps.is_installed("your_dev_app"):
return loader.discover(start_dir=dirname(abspath(__file__)), pattern=pattern)
When you run:
python manage.py test
the command will look per default recursive for all files with the pattern test*.py in the working directory. It isn't affected by INSTALLED_APPS in settings.py.
You can specify a certain app to test it:
python manage.py test app_label
or specify a path:
python manage.py test myapp/tests
If you want to exclude some tests you can tag them and use the option --exclude-tag.
Run python manage.py test --help to get information on all options.
The official documentation gives a lot of information on the different possibilities how to run the tests.
EDIT:
If you have apps that are required only in the development environment, but not in the production, you could split your settings.py. One possible solution would be to outsource all development settings into a file local_settings.py and exclude it from versioning or from the production branch, i.e. don't push it in the production environment.
local_settings.py
DEBUG = True
INSTALLED_APPS += (
# Django Debug Toolbar would be for example
# used only in development
'debug_toolbar',
'your dev app',
)
settings.py
try:
from .local_settings import *
except ImportError:
pass

Django makemigrations not detecting project/apps/myapp

Solved
Interesting:
./manage.py makemigrations apps.myapp -> "App 'apps.myapp' could
not be found. Is it in INSTALLED_APPS?"
./manage.py makemigrations myapp -> Works.
./manage.py makemigrations -> "No changes detected" (it does detect changes if myapp is in the project root)
Original question:
Project structure
myproject/
myproject/
apps/
myapp/
__init__.py
admin.py
models.py
urls.py
views.py
tests.py
myapp2/
myapp3/
__init__.py
static/
templates/
virtualenv/
manage.py
myproject/apps/myapp/models.py
from django.db import models
class MyModel(models.Model):
name = models.CharField(max_length=200)
created = models.DateTimeField(auto_now_add=True)
Settings.py
INSTALLED_APPS = [
# ...
'apps.myapp',
'apps.myapp2',
'apps.myapp3',
]
makemigrations cannot find "myapps" that's not in the project root.
At the same time, migrate does find it.
$ ./manage.py makemigrations apps.myapp
App 'apps.myapp' could not be found. Is it in INSTALLED_APPS?
$ ./manage.py migrate apps.myapp
CommandError: App 'apps.myapp' does not have migrations.
Isn't the "let's put our apps into an apps folder" practise valid any more, am I doing something wrong, or is it a bug of the makemigrations command?
Note1: before running makemigrations, I removed the "migrations" folder of myapp, but I'm pretty sure it doesn't matter. It did get re-created when the app was in the project root.
Note2: I did research google and stackoverflow, I only found similar questions where the solution was either "adding the app to settings.py", "running makemigrations before migrate" or "some migration issue between Django 1.6 and 1.7". None of these apply to my situation, I think.
You may have deleted the migrations folder inside the app or __init__.py inside the <app>/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
try
INSTALLED_APPS = [
# ...
'myproject.apps.myapp',
]
and
python manage.py makemigrations myapp
It's works now. It didn't work before because I didn't make any changes to my model.
I'm new to django and was trying to execute the command from the videos I watched. Django documentation tells you that makemigrations create new migrations based on the changes you made to your model. So, I make changes in models.py and admin.py and it's working now.
I had the same problem. I solved it by adding "migrations" file into the app folders.

Import relative apps in Django

I'm new to Django and have a question about app structure and imports. My project structure looks like this (from deploydjango.com):
root/
manage.py
mysite/
__init__.py
urls.py
wsgi.py
settings/
apps/
__init__.py
profile
__init__.py
models.py
views.py
video
__init__.py
models.py
views.py
photos
__init__.py
models.py
views.py
Basically I will have some profiles on my site, where each profile then have a number of uploaded photos and videos. So in my video model I have the following code:
from django.db import models
from XXXXX import Profile
class Video(models.Model):
# more fields
company = models.ForeignKey(Profile, related_name='videos')
How do I import the Profile model for use in the Video model? Or is my structure not suitable..? What would be best practice for this?
I think your structure is fine. Basically, python's modules are just a python file which you may import like this: import <filename> and you will have its functionality imported. But when you group some python files in a folder and include in that folder a file called init.py there you have a python package. With is a better way to manage a group of modules and it allows the dot notation in your imports. Django apps behave like packages as you may see.
If you want to import Profile within your video module then you have to do this:
from profile.models import Profile
That is, assuming that the Profile model is defined in your profile app in models.py. That should do.
If you want more information about python project structure this is a great place.

Scrapy project can't find django.core.management

I'm trying to follow the method here to 'Scrapy' data from the web and simultaneously save that data directly to my Django database using Scrapy's item pipeline.
However, when I try to run scrapy crawl spidername, I'm getting the error:
ImportError: No module named django.core.management
At first I thought it was because my Scrapy project was outside of my Django project folder, but even after I moved the whole project into my Django project folder I kept getting the same error. If I open a python shell inside the Scrapy project folder in its new location (inside my Django project folder), import django.core.management works fine. So what's going on?
EDIT: Some additional info: I'm doing this on a Webfaction server, and the path to my Django project is /home/gchorn/webapps/django_app/django_project. I'm using Django version 1.4.1, Scrapy 0.16 and Python2.7. The layout of the Django+Scrapy project is as follows:
django_project/
__init__.py
manage.py
settings.py
urls.py
myproject #folder containing wsgi.py
app1
app2
app3
templates
ScrapyProject/
scrapy.cfg
ScrapyProject/
__init__.py
items.py
pipelines.py
settings.py
spiders/
__init__.py
my_spider.py
Try setting this in your Spider's settings.py:
import os
import sys
sys.path.append('/home/gchorn/webapps/django_app')
os.environ['DJANGO_SETTINGS_MODULE'] = 'django_project.settings'
Then you can import your model classes like:
from django_project.app1.models import some_model