Django 1.8 and nose: conflicting models? - django

I have a Django application I recently upgraded to Django 1.8.4. I'm using nose 1.3.7 and django-nose 1.4.1 for my test runner to run over 200 integration and unit tests. Since upgrading both Django and nose, I'm finding that 12 of my tests fail with this same error:
======================================================================
ERROR: Failure: RuntimeError (Conflicting 'c' models in application 'nose': <class 'account.tests.form_tests.TestAddress'> and <class 'nose.util.C'>.)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/me/venv/myproj/lib/python2.7/site-packages/nose/loader.py", line 523, in makeTest
return self._makeTest(obj, parent)
File "/Users/me/venv/myproj/lib/python2.7/site-packages/nose/loader.py", line 568, in _makeTest
obj = transplant_class(obj, parent.__name__)
File "/Users/me/venv/myproj/lib/python2.7/site-packages/nose/util.py", line 644, in transplant_class
class C(cls):
File "/Users/me/venv/myproj/lib/python2.7/site-packages/django/db/models/base.py", line 311, in __new__
new_class._meta.apps.register_model(new_class._meta.app_label, new_class)
File "/Users/me/venv/myproj/lib/python2.7/site-packages/django/apps/registry.py", line 223, in register_model
(model_name, app_label, app_models[model_name], model))
RuntimeError: Conflicting 'c' models in application 'nose': <class 'account.tests.form_tests.TestAddress'> and <class 'nose.util.C'>.
What's curious is that the form_tests.py module doesn't even reference TestAddress which is actually a class inside my "profiles" model:
# myprof/profile/models.py
class TestAddress(models.Model):
user = models.OneToOneField(User, primary_key=True, unique=True)
address_line_1 = models.CharField(max_length=30)
address_line_2 = models.CharField(max_length=30, null=True, blank=True)
city = models.CharField(max_length=30)
region = models.CharField(max_length=30, null=True, blank=True)
postal_code = models.CharField(max_length=10, null=True, blank=True)
country = models.ForeignKey('Country')
class Meta:
db_table = 'test_address'
def __unicode__(self):
return u'%s' % (self.user.username)
When my tests need to generate an instance of the TestAddress class, I use a factory_boy (v. 2.5.2) factory:
# utils/factories.py
from profile.models import TestAddress
class UserFactory(factory.django.DjangoModelFactory):
class Meta:
model = User
username = 'testuser'
class TestAddressFactory(factory.django.DjangoModelFactory):
class Meta:
model = TestAddress
user = factory.SubFactory('utils.factories.UserFactory')
address_line_1 = '123 Main St.'
address_line_2 = 'Apt. A'
city = 'AnyCity'
region = 'AnyRegion'
postal_code = '12345'
country = factory.SubFactory('utils.factories.CountryFactory')
I set breakpoints in the nose loader.py module and confirmed that loader sees "TestAddress" in "profile.models". However, there is a "parent.__name__" variable there which is set to "account.tests.model_tests". I have a couple of questions:
1. Why is this occurring?
2. Is there a way I can fix it?
3. Is there some way I can get nose to tell me which tests are resulting in these runtime errors so that I can at least disable them if I can't fix the problem?
I set "--verbosity=2" but that
doesn't display the names of failing tests. I looked through the nose docs and didn't see anything. Worst case I can write a script to call every test individually and echo the test name before running it but that seems very ugly and time-consuming.
Thanks.

I ran into the same issue while porting my Django project from 1.6 to 1.8 and updating django-nose to 1.4.3.
It appears that with the new DiscoverRunner used in 1.7 onwards, django-nose attempts to run all classes beginning with Test* as Test Cases, which leads to them being adapted into django-nose's django app before they are encountered in test modules.
I managed to resolve this issue by renaming them to avoid this naming scheme, to things like AdressTestModel.

I just encountered this and solved it with the #nottest decorator.
Technically, it's for functions according to the docs, but decorating classes with it also works:
from nose.tools import nottest
#nottest
class TestAddressFactory(...):
...
All the decorator does is add __test__ with the value True to the object it is decorating.
def nottest(func):
"""Decorator to mark a function or method as *not* a test
"""
func.__test__ = False
return func

Related

ValueError in models.py

Here is my models.py file. When I try to migrate it gives me an error.
I changed Class name and it gives me an error. Now if I put even old name, it gives me the same error
from django.db import models
from tinymce.models import HTMLField
class BlockTags(models.Model):
pass
class BlockTags_Text(models.Model):
text = models.CharField(max_length=300, verbose_name='Заголовок 1', null=True, blank=True)
block = models.ForeignKey(BlockTags, related_name="text", verbose_name='Заголовок 1', on_delete=models.CASCADE, null=True,blank=True)
number = models.DecimalField(max_digits=3, decimal_places=0)
ValueError: The field content.BlockTags.text was declared with a lazy reference to 'content.blocktags_text', but app 'content' doesn't provide model 'blocktags_text'.
(venv) appledeMacBook-Pro:letbuycar apple$
app 'content' doesn't provide model 'blocktags_text'.
This means that django doesnt see a blocktags_text model in your models.py, try running makemigrations and then migrate, also try adding at least one field to your empty model.

DJANGO Install application on runtime

I have an application which is made of several apps. The thing is that by default, only 1 app is installed. I called it 'base'. This base app enables the user to manage users, groups (but that isn't the point here) AND should enable users to install other apps on runtime (that is the point).
I created an Application model.
In my UI, I list all the applications with a button install aside of it.
The idea is, when I click on this button, to :
Mark the application as installed
Add it to the App registry on runtime (that's the blocking point)
Apply the migration for this app
So here are some samples of code :
My Application model :
from django.apps import apps
from django.conf import settings
from django.core import management
from django.db import models
class Application(models.Model):
class Meta:
db_table = 'base_application'
name = models.CharField(max_length=255, unique=True)
verbose_name = models.CharField(max_length=255)
version = models.CharField(max_length=255, null=True, blank=True)
summary = models.CharField(max_length=255)
description = models.TextField(null=True, blank=True)
is_installed = models.BooleanField(default=False)
is_uninstallable = models.BooleanField()
My install() method would look like :
I know there are mistakes in it and that is the point of this question. I don't understand how the App Registry actually works.
Note that I must provide the reverse of it too (uninstall)
def install(self):
self.is_installed = True
self.save()
settings.INSTALLED_APPS.append(self.name)
apps.populate(settings.INSTALLED_APPS)
self.migrate()
My migrate() method :
def migrate(self):
management.call_command('makemigrations', self.name, interactive=False)
management.call_command('migrate', self.name, interactive=False)
The usual error I get is No installed app with label ....
Thanks in advance for your help. I can precise if needed.

System check identified 3 issues (0 silenced)

what could the issue with my model.py .i have tried everything nothing happens.and i think i defined my foreign key the right way .could it be a problem with my defining or do i have to use memberid.user in my foreginkey or what would be effect.any contribution is welcomed.
Performing system checks...
Unhandled exception in thread started by <function wrapper at 0x7f6a926d69b0>
Traceback (most recent call last):
File "/usr/lib64/python2.7/site-packages/django/utils/autoreload.py", line 227, in wrapper
fn(*args, **kwargs)
File "/usr/lib64/python2.7/site-packages/django/core/management/commands/runserver.py", line 125, in inner_run
self.check(display_num_errors=True)
File "/usr/lib64/python2.7/site-packages/django/core/management/base.py", line 405, in check
raise SystemCheckError(msg)
django.core.management.base.SystemCheckError: SystemCheckError: System check identified some issues:
ERRORS:
tithe.tithe.memberid: (fields.E300) Field defines a relation with model 'memberid', which is either not installed, or is abstract.
tithe.tithe.memberid: (fields.E307) The field tithe.tithe.memberid was declared with a lazy reference to 'tithe.memberid', but app 'tithe' doesn't provide model 'memberid'.
tithe.tithe: (models.E012) 'unique_together' refers to the non-existent field 'IntegerField'.
System check identified 3 issues (0 silenced).
Performing system checks...
Unhandled exception in thread started by <function wrapper at 0x7f3d3ccdc9b0>
Traceback (most recent call last):
File "/usr/lib64/python2.7/site-packages/django/utils/autoreload.py", line 227, in wrapper
fn(*args, **kwargs)
File "/usr/lib64/python2.7/site-packages/django/core/management/commands/runserver.py", line 125, in inner_run
self.check(display_num_errors=True)
File "/usr/lib64/python2.7/site-packages/django/core/management/base.py", line 405, in check
raise SystemCheckError(msg)
django.core.management.base.SystemCheckError: SystemCheckError: System check identified some issues:
ERRORS:
tithe.tithe.memberid: (fields.E300) Field defines a relation with model 'User', which is either not installed, or is abstract.
tithe.tithe.memberid: (fields.E307) The field tithe.tithe.memberid was declared with a lazy reference to 'tithe.user', but app 'tithe' doesn't provide model 'user'.
tithe.tithe: (models.E012) 'unique_together' refers to the non-existent field 'IntegerField'.
this my model.py code
from django.utils import timezone
from django.db import models
# Create your models here.
class tithe(models.Model):
memberid = models.ForeignKey('User')
membername = models.CharField(max_length=45)
receitcode = models.CharField(max_length=45)
tithes = models.IntegerField()
combinedoffering = models.IntegerField()
campmeetingoffering = models.IntegerField()
churchbuilding = models.IntegerField()
conference = models.IntegerField()
localchurch = models.IntegerField()
funds = models.IntegerField()
total = models.IntegerField()
created_date = models.DateTimeField(
default=timezone.now)
published_date = models.DateTimeField(
blank=True, null=True)
def publish(self):
self.published_date = timezone.now()
self.save()
def __str__(self):
return self.receitcode
class Meta:
unique_together = ["receitcode","IntegerField"]
ordering = ["published_date","membername"]
The line below
memberid = models.ForeignKey('User')
is causing the problem. You have to pass a User object to it.
Import User model.
from django.contrib.auth.models import User
then
memberid = models.ForeignKey(User)
The first two warnings are because Django cannot find the model 'User' that you refer to in the memberid foreign key.
I recommend you use settings.AUTH_USER_MODEL to reference the user model. This will work whether or not you have a custom user model.
memberid = models.ForeignKey(settings.AUTH_USER_MODEL)
See the docs for more info on referencing the user model.
Note that it would be better to call name your field member. That way, the related instance will be member and the related id will be member_id. At the moment, the related instance is memberid, and the related id is memberid_id.
The final warning is because you do not have a field IntegerField in the model. If you want the receitcode field to be unique by itself, then remove the unique_together line and change the field to:
receitcode = models.CharField(max_length=45, unique=True)
Your ForeignKey needs to reference a concrete model or abstract model. Since you are referencing using a string (which means the model is abstract) you need to declare the class Meta: as abstract by stating abstract = True
Relationships defined this way on abstract models are resolved when the model is subclassed as a concrete model and are not relative to the abstract model’s app_label:
The below information is from the Django Documentation https://docs.djangoproject.com/en/1.11/ref/models/fields/
products/models.py
from django.db import models
class AbstractCar(models.Model):
manufacturer = models.ForeignKey('Manufacturer', on_delete=models.CASCADE)
# This is what you need to add
class Meta:
abstract = True

Default value generating a UUID breaks migrations in django 1.7, is there a workaround?

Django 1.7 now requires that migrations be setup. Unfortunately, using lambdas or similar in default field values breaks this process.
I have the following in a model:
def make_uuid(type):
"""Takes an entity type identifier string as input and returns a hex of UUID2 with a
type identifier pre-pended for readability"""
return str(type)+str(uuid.uuid1().hex)
class Accounts(models.Model):
"""Model representing Accounts"""
PENDING_STATUS = 0
ACTIVE_STATUS = 1
SUSPENDED_STATUS = 2
CANCELLED_STATUS = 3
BETA_STATUS = 4
STATUS_CHOICES = (
(PENDING_STATUS, 'Pending'),
(ACTIVE_STATUS, 'Active'),
(SUSPENDED_STATUS, 'Suspended'),
(CANCELLED_STATUS, 'Cancelled'),
(BETA_STATUS, 'Beta'),
)
account_name = models.CharField(max_length=255)
account_uuid = models.CharField(max_length=34, default=partial(make_uuid,'AC'), db_index=True, unique=True)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
updated_by = models.ForeignKey(User, null=True, blank=True)
status = models.IntegerField(max_length=2, choices=STATUS_CHOICES, default=PENDING_STATUS)
The call to partial breaks the migration process with the following error:
ValueError: Cannot serialize: <functools.partial object at 0x10e5cf9f0>
There are some values Django cannot serialize into migration files.
I still need to auto-generate the UUID, so does anyone know of a workaround to this that doesn't break migrations?
The issue here is that the migrations system needs to serialize the function definition, and isn't able to do so with the dynamically-created object returned by partial().
(Note that as of version 1.9 Django is in fact able to serialize partial() callables, and the code above would work.)
To fix this use a module-level function instead:
def make_uuid_ac():
return make_uuid('AC')
class Accounts(models.Model):
....
account_uuid = models.CharField(..., default=make_uuid_ac)
If you need to pass args to the function (that is for partial) there is solution in docs:
from django.utils.deconstruct import deconstructible
#deconstructible
class MakeUUID(object):
def __init__(self, pre):
self.pre = pre
def __call__(self, obj, *args):
return '{}-{}-{}'.format(self.pre,
obj.__class__.__name__,
uuid.uuid1().hex)
make_uuid = MakeUUID('AC')
Also type as an argument name is not a good idea.
Re-read the documentation: ​https://docs.djangoproject.com/en/1.8/ref/models/fields/#uuidfield
Note that a callable (with the parentheses omitted) is passed to default, not an instance of UUID.

Import app model class in another app model

I got 2 app: coworkers and services, each one with its own models.py
In coworkers models.py, I can "from services.models import Services".
When I try to "from coworkers.models import Status" in services models.py, I get this error message:
Traceback (most recent call last): File
"/Users/lucas/Documents/projetos/cwk-manager/lib/python2.7/site-packages/Django-1.4.3-py2.7.egg/django/core/management/commands/runserver.py",
line 91, in inner_run
self.validate(display_num_errors=True) File "/Users/lucas/Documents/projetos/cwk-manager/lib/python2.7/site-packages/Django-1.4.3-py2.7.egg/django/core/management/base.py",
line 266, in validate
num_errors = get_validation_errors(s, app) File "/Users/lucas/Documents/projetos/cwk-manager/lib/python2.7/site-packages/Django-1.4.3-py2.7.egg/django/core/management/validation.py",
line 30, in get_validation_errors
for (app_name, error) in get_app_errors().items(): File "/Users/lucas/Documents/projetos/cwk-manager/lib/python2.7/site-packages/Django-1.4.3-py2.7.egg/django/db/models/loading.py", line 158, in get_app_errors
self._populate() File "/Users/lucas/Documents/projetos/cwk-manager/lib/python2.7/site-packages/Django-1.4.3-py2.7.egg/django/db/models/loading.py", line 64, in _populate
self.load_app(app_name, True) File "/Users/lucas/Documents/projetos/cwk-manager/lib/python2.7/site-packages/Django-1.4.3-py2.7.egg/django/db/models/loading.py", line 88, in load_app
models = import_module('.models', app_name) File "/Users/lucas/Documents/projetos/cwk-manager/lib/python2.7/site-packages/Django-1.4.3-py2.7.egg/django/utils/importlib.py",
line 35, in import_module
import(name) File "/Users/lucas/Documents/projetos/cwk-manager/cwk-manager/cwk_manager/coworkers/models.py",
line 2, in
from services.models import Services File "/Users/lucas/Documents/projetos/cwk-manager/cwk-manager/cwk_manager/services/models.py",
line 5, in
class Services(models.Model): File "/Users/lucas/Documents/projetos/cwk-manager/cwk-manager/cwk_manager/services/models.py",
line 11, in Services
status = models.ForeignKey(Status) NameError: name 'Status' is not defined
--
coworker models.py
from django.db import models
from services.models import Services
class Status(models.Model):
status_name = models.CharField(max_length=50)
status_description = models.TextField(blank=True, null=True)
class Meta:
verbose_name = "Status"
verbose_name_plural = "Status"
def __unicode__(self):
return self.status_name
services models.py
from django.db import models
from coworkers.models import Status
# This table contains all the information about plans and other general services provided.
class Services(models.Model):
service_name = models.CharField(max_length=100)
service_description = models.TextField(blank=True, null=True)
service_price = models.DecimalField(max_digits=7, decimal_places=2, blank=True, null=True)
creation_date = models.DateField(auto_now_add=True)
last_update = models.DateField(auto_now=True)
status = models.ForeignKey(Status)
class Meta:
verbose_name = "Services"
verbose_name_plural = "Services"
def __unicode__(self):
return self.service_name
--
Can someone help me to see what I am doing wrong?
Thanks in advance!
This is caused by circular import in Python.
You can use this syntax:
status = models.ForeignKey('coworkers.models.Status')
Django will determine model using this path so you don't need to import Status.
Another solution in your case would be to delete 2nd import statement in coworker.models because Services doesn't seem to be used in this file.
In Django 1.6.5 this:
import coworkers
status = models.ForeignKey(coworkers.models.Status)
Should be this:
import coworkers
status = models.ForeignKey(coworkers.Status)
I am (now) aware the the OP is using Django 1.4.3 and that some of the answers may solve this in that version of Django. However, it took me a while to notice the version and those answers do not work in 1.6.5.
Cheers!
It's circularly import, which results errors.
You can try,
import coworkers
status = models.ForeignKey(coworkers.models.Status)
Just create the Status model first and do syncdb and after that create the services model and syncdb. It should work.
The problem is that python is not ab le to find the 'Status' coz its first trying to create the Services model.
I got all sorts of errors like this while doing syncdb:
CommandError: One or more models did not validate: parts.vehicle:
'customer' has a relation with model <class
'customers.models.Customer'>, which has either not been installed or
is abstract.
I finally realized I had forgotten to add the new app to settings.py. Admin couldn't find it either. That should have been my first clue. Otherwise I was doing what was in the answer by e.thompsy for django 1.6.5