charettes / django-mutant Goto Github PK
View Code? Open in Web Editor NEWDynamic model definition and alteration (evolving schemas)
Home Page: https://pypi.python.org/pypi/django-mutant
License: MIT License
Dynamic model definition and alteration (evolving schemas)
Home Page: https://pypi.python.org/pypi/django-mutant
License: MIT License
Hi Simon,
I have created a new model as following:
account_model_def = ModelDefinition.objects.get_or_create(
app_label='accounts',
object_name='Account',
defaults={'fields': [CharFieldDefinition(name='char_field', max_length=25)]}
)
Normally I would use Accounts.objects.all() to retrieve all objects in a view.
How does this work with regard to django-mutant?
Thanks
Hi charettes,
it seems models.FieldDefinition can register in django admin page,
but when i filled the form and click the save button
it gives the error page, and say FieldDefinition didn't define any field_class
.
NotImplementedError at /admin/mutant/fielddefinition/add/
FieldDefinition didn't define anyfield_class
.
Request Method: POST
Request URL: http://localhost:8000/admin/mutant/fielddefinition/add/
so how to define a customized field ,
I think it is useful for new bee to understand about dynamic model
otherwise ,I want to store my customized fields in a table ,what should I do?
I was following the instructions from http://integricho.github.io/2013/07/22/mutant-introduction/ in order to get started with my own django-mutant experiments.
When trying to sync the db, i get the following error:
$ python manage.py syncdb
Syncing...
Creating tables ...
Creating table mutant_modeldefinition
Creating table mutant_basedefinition
Creating table mutant_orderingfielddefinition
Creating table mutant_uniquetogetherdefinition_field_defs
Creating table mutant_uniquetogetherdefinition
Creating table mutant_fielddefinition
Creating table mutant_fielddefinitionchoice
DatabaseError: (1170, "BLOB/TEXT column 'group' used in key specification without a key length")
What am I doing wrong?
/edit: I'm using MySQL as backend.
I have tried to create a new field with a unique constraint where I already have a field with null values. So when I tried to create a field, It returns django.db.utils.IntegrityError. But the field is created in mutant_fielddefinition table when I check the DB. This breaks the CRUD functionality
FieldDefinition didn't define any field_class
.
Requirements: django 1.6.4, django-mutant=0.1.2
The app has multiple failures and do not support symmetric
M2M. This might have something to do with deferred SQL.
When starting a new project, the manage.py makemigrations
command fails:
$ django-admin2 startproject mutantest
$ cd mutantest/
$ virtualenv venv
$ source venv/bin/activate
$ pip install django-mutant
$ vim mutantest/settings.py
Add 'mutant' to INSTALLED_APPS
$ pip list
Django (1.9.6)
django-mutant (0.2.1)
django-picklefield (0.3.2)
django-polymodels (1.4.4)
pip (8.1.2)
setuptools (21.2.1)
wheel (0.29.0)
$ ./manage.py makemigrations
Traceback (most recent call last):
File "./manage.py", line 10, in <module>
execute_from_command_line(sys.argv)
File "/tmp/mutantest/venv/lib/python2.7/site-packages/django/core/management/__init__.py", line 353, in execute_from_command_line
utility.execute()
File "/tmp/mutantest/venv/lib/python2.7/site-packages/django/core/management/__init__.py", line 345, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/tmp/mutantest/venv/lib/python2.7/site-packages/django/core/management/base.py", line 348, in run_from_argv
self.execute(*args, **cmd_options)
File "/tmp/mutantest/venv/lib/python2.7/site-packages/django/core/management/base.py", line 399, in execute
output = self.handle(*args, **options)
File "/tmp/mutantest/venv/lib/python2.7/site-packages/django/core/management/commands/makemigrations.py", line 132, in handle
migration_name=self.migration_name,
File "/tmp/mutantest/venv/lib/python2.7/site-packages/django/db/migrations/autodetector.py", line 46, in changes
changes = self._detect_changes(convert_apps, graph)
File "/tmp/mutantest/venv/lib/python2.7/site-packages/django/db/migrations/autodetector.py", line 132, in _detect_changes
self.new_apps = self.to_state.apps
File "/tmp/mutantest/venv/lib/python2.7/site-packages/django/utils/functional.py", line 33, in __get__
res = instance.__dict__[self.name] = self.func(instance)
File "/tmp/mutantest/venv/lib/python2.7/site-packages/django/db/migrations/state.py", line 162, in apps
return StateApps(self.real_apps, self.models)
File "/tmp/mutantest/venv/lib/python2.7/site-packages/django/db/migrations/state.py", line 228, in __init__
self.render_multiple(list(models.values()) + self.real_models)
File "/tmp/mutantest/venv/lib/python2.7/site-packages/django/db/migrations/state.py", line 296, in render_multiple
model.render(self)
File "/tmp/mutantest/venv/lib/python2.7/site-packages/django/db/migrations/state.py", line 585, in render
body,
File "/tmp/mutantest/venv/lib/python2.7/site-packages/django/db/models/base.py", line 292, in __new__
new_class._meta.apps.register_model(new_class._meta.app_label, new_class)
File "/tmp/mutantest/venv/lib/python2.7/site-packages/django/db/migrations/state.py", line 325, in register_model
self.do_pending_operations(model)
File "/tmp/mutantest/venv/lib/python2.7/site-packages/django/apps/registry.py", line 406, in do_pending_operations
function(model)
File "/tmp/mutantest/venv/lib/python2.7/site-packages/django/apps/registry.py", line 388, in function
self.lazy_model_operation(next_function, *more_models)
File "/tmp/mutantest/venv/lib/python2.7/site-packages/django/apps/registry.py", line 397, in lazy_model_operation
function(model_class)
File "/tmp/mutantest/venv/lib/python2.7/site-packages/polymodels/fields.py", line 113, in resolve_polymorphic_type
field.validate_polymorphic_type(related_model)
File "/tmp/mutantest/venv/lib/python2.7/site-packages/polymodels/fields.py", line 103, in validate_polymorphic_type
"First parameter to `PolymorphicTypeField` must be "
AssertionError: First parameter to `PolymorphicTypeField` must be a subclass of `BasePolymorphicModel`
If there is a model defined that has a relation to the mutant ModelDefinition model, the whole migration chain breaks up.
The reason that this happens is that the "contenttypes 0002_remove_content_type_name" migration needs to run before the mutant initial migration. Because of this, things like running tests ( that require a database to be made )
or migrating from scratch will not work.
A possible fix is to modify the 0001_initial.py mutant migration file and change the depedencies to dependencies = [ ('contenttypes', '0002_remove_content_type_name'), ]
Here is the mentioned error
Hi, @charettes .
Thanks for your great job for django-mutant.
I am trying to make use following the steps here-A getting started guide.
However, here comes some issues :
1.
__init__() missing 1 required positional argument: 'queryset'
which is caused from github repo of "A getting started guide"
def get_field_def_form(field_type_pk, model_def_queryset):
'''
to dynamically create self.form_class for FIELDCREATE view
'''
class Meta:
model = get_mutant_type(field_type_pk)
form_attrs = {
'Meta': Meta,
'content_type': FieldDefinitionTypeField(widget=forms.HiddenInput),#this line,
'model_def': forms.ModelChoiceField(queryset=model_def_queryset,
widget=forms.HiddenInput)
}
return type('FieldDefinitionForm', (forms.ModelForm,), form_attrs)
line 23
'content_type': FieldDefinitionTypeField(widget=forms.HiddenInput),
I don't know how to fix it while I want to dynamically create a model/table.(I clearly know I SHOULD add a queryset to fix it , but ,how to generate a queryset for the field_type? )
Also, I found that there are 2 FieldDefinitionTypeField
class in your repo ,is that a kind of typo ? One is located "db.fields.", the other is located "mutant.forms".
Lastly. How to fill data into a table(OF COURCE BY DJANGO, NOT BY PYTHON/MYSQL ONLY), while there is no a related model in the admin and no way to initialize an instance?(We can just see ModelDefinition FieldDefinition in admin,but a specific model mapping to the model. I don't know whether the questions is clear)
How to register a dynamic class? While I register it by
admin.site.register(models.ModelDefinition.objects.filter(app_label='app_label',model='model',object_name='object_name')[0].construct(),modelAdmin)
I get the error as AttributeError: 'MutantConfig' object has no attribute 'state_handler'
.
I just have no idea how to make use of it.
Here's the log:
Unhandled exception in thread started by <function check_errors..wrapper at 0x1138eb400>
Traceback (most recent call last):
File "/Users/NoraChan/Desktop/geekhacker.tech/web_virtualenv/lib/python3.4/site-packages/django/utils/autoreload.py", line 226, in wrapper
fn(args, **kwargs)
File "/Users/NoraChan/Desktop/geekhacker.tech/web_virtualenv/lib/python3.4/site-packages/django/core/management/commands/runserver.py", line 113, in inner_run
autoreload.raise_last_exception()
File "/Users/NoraChan/Desktop/geekhacker.tech/web_virtualenv/lib/python3.4/site-packages/django/utils/autoreload.py", line 249, in raise_last_exception
six.reraise(_exception)
File "/Users/NoraChan/Desktop/geekhacker.tech/web_virtualenv/lib/python3.4/site-packages/django/utils/six.py", line 685, in reraise
raise value.with_traceback(tb)
File "/Users/NoraChan/Desktop/geekhacker.tech/web_virtualenv/lib/python3.4/site-packages/django/utils/autoreload.py", line 226, in wrapper
fn(*args, **kwargs)
File "/Users/NoraChan/Desktop/geekhacker.tech/web_virtualenv/lib/python3.4/site-packages/django/init.py", line 27, in setup
apps.populate(settings.INSTALLED_APPS)
File "/Users/NoraChan/Desktop/geekhacker.tech/web_virtualenv/lib/python3.4/site-packages/django/apps/registry.py", line 115, in populate
app_config.ready()
File "/Users/NoraChan/Desktop/geekhacker.tech/web_virtualenv/lib/python3.4/site-packages/django/contrib/admin/apps.py", line 23, in ready
self.module.autodiscover()
File "/Users/NoraChan/Desktop/geekhacker.tech/web_virtualenv/lib/python3.4/site-packages/django/contrib/admin/init.py", line 26, in autodiscover
autodiscover_modules('admin', register_to=site)
File "/Users/NoraChan/Desktop/geekhacker.tech/web_virtualenv/lib/python3.4/site-packages/django/utils/module_loading.py", line 50, in autodiscover_modules
import_module('%s.%s' % (app_config.name, module_to_search))
File "/Users/NoraChan/Desktop/geekhacker.tech/web_virtualenv/lib/python3.4/importlib/init.py", line 109, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "", line 2254, in _gcd_import
File "", line 2237, in _find_and_load
File "", line 2226, in _find_and_load_unlocked
File "", line 1200, in _load_unlocked
File "", line 1129, in _exec
File "", line 1471, in exec_module
File "", line 321, in _call_with_frames_removed
File "/Users/NoraChan/Desktop/geekhacker.tech/Datadriven_Website/dataset/admin.py", line 18, in
obj = models.ModelDefinition.objects.filter(app_label='explorer',model='ad0',object_name='ad0')[0].construct()
File "/Users/NoraChan/Desktop/geekhacker.tech/web_virtualenv/lib/python3.4/site-packages/django/db/models/query.py", line 295, in getitem
return list(qs)[0]
File "/Users/NoraChan/Desktop/geekhacker.tech/web_virtualenv/lib/python3.4/site-packages/django/db/models/query.py", line 256, in iter
self._fetch_all()
File "/Users/NoraChan/Desktop/geekhacker.tech/web_virtualenv/lib/python3.4/site-packages/django/db/models/query.py", line 1087, in _fetch_all
self._result_cache = list(self.iterator())
File "/Users/NoraChan/Desktop/geekhacker.tech/web_virtualenv/lib/python3.4/site-packages/django/db/models/query.py", line 66, in iter
obj = model_cls.from_db(db, init_list, row[model_fields_start:model_fields_end])
File "/Users/NoraChan/Desktop/geekhacker.tech/web_virtualenv/lib/python3.4/site-packages/django/db/models/base.py", line 565, in from_db
new = cls(*values)
File "/Users/NoraChan/Desktop/geekhacker.tech/django-mutant/mutant/models/model/init.py", line 189, in init
self._model_class = self.model_class().model
File "/Users/NoraChan/Desktop/geekhacker.tech/django-mutant/mutant/models/model/init.py", line 304, in model_class
model_class = self.construct(force_create, model_class)
File "/Users/NoraChan/Desktop/geekhacker.tech/django-mutant/mutant/models/model/init.py", line 274, in construct
state_handler.set_checksum(self.pk, checksum)
File "/Users/NoraChan/Desktop/geekhacker.tech/django-mutant/mutant/state/utils.py", line 10, in getattribute
handler = apps.get_app_config('mutant').state_handler
AttributeError: 'MutantConfig' object has no attribute 'state_handler'
If you can help answer it or give some direction/tips, I would appreciate so much.
Hi,
I'm using mutant to create models at run time for a survey creation application.
To create a new survey, I first create a survey definition file and then create a model, using mutant, according to that survey definition file. I first create a ModelDefinition
and then create a FieldDefinition
(one of its sub-classes, to be precise) for every question.
To change a survey, I first delete the current ModelDefinition
and create a new one.
The problem is that for every creation of a FieldDefinition
mutant does a lot of stuff to keep the sate of the model correct. For a large survey, with dozens of fields, this can amount to thousands of SQL queries. I think that for this use case, these actions are redundant because I'm only interested in the state of the model after the last field has been created (I will never use the half-baked model). After the last field is created, I call model_class(force_create=True)
on the new ModelDefinition
instance to make sure the state is correct.
To improve performance, I commented out the line self.model_def.model_class(force_create=force_create)
at ModelDefinitionAttribute.save()
This decreased the number of queries and the run-time and haven't affected the correctness of the program so far.
Well, commenting out this line is obviously not an appropriate solution. How would you recommend to solve this?
I also noticed that field_definition_post_save
is called after every field is created. This also causes a lot of redundant queries as the table is dropped and re-created for every field creation. Every time the number of columns is increased by 1.
ImportError: cannot import name 'force_unicode'
installed in my virtualenv:
bbcode==1.0.21
Django==1.8.3
django-annoying==0.8.3
django-mutant==0.1.2
django-picklefield==0.3.1
django-polymodels==1.3.1
django-registration-redux==1.2
Pillow==2.9.0
psycopg2==2.6.1
six==1.9.0
sorl-thumbnail==12.3
South==1.0.2
Unidecode==0.4.18
wheel==0.24.0
and using Python3.4.3
I just put it in the installed apps and ran pip install django-mutant; However I'm not sue if there are supposed to be other requirements?
Hi,
I've looked at the following examples:
charettes/django-mutant-usecase.rst
I have a lot of already defined "static models" in my models.py. Can mutant be used to extend them, or do they have to be redefined using ModelDefinition.objects.create()?
I thought I could create a ModelDefinition for one of my pre-existing models and it would recognize that it didn't need to create any new database tables and/or content-types, and would simply allow my to add more fields to my model.
Instead I got a UNIQUE constraint error when it tried to insert a duplicate contenttype.
Am I misunderstanding the usage of this package? Can MutableModel be used as a base class for my models instead of django.models.Model or perhaps add ModelDefinitionAttribute as a mixin?
Any help would be appreciated,
-Scott
Hey,
I'm trying to add/remove/modify several fields in an existing model (with existing table).
Currently, I'm doing it by deleting/creating FieldDefinition
one at a time, this result in a lot of SQL queries.
It seems the code below is in-charge of altering an existing model, but I'm not so sure how to reach it.
def base_definition_post_save(sender, instance, created, raw, **kwargs):
declared_fields = instance.get_declared_fields()
if declared_fields:
....
if created:
...
else:
for field in declared_fields:
try:
old_field = opts.get_field(field.name)
except FieldDoesNotExist:
perform_ddl(model_class, 'add_column', table_name,
field.name, field, keep_default=False)
else:
column = old_field.get_attname_column()[1]
perform_ddl(model_class, 'alter_column', table_name,
column, field)
base_definition_post_save()
called?get_declared_fields()
so it will include the new and modified fields?declared_fields
, will adding this loop after the for loop above work?declared_fields_names = {field.name for field in declared_fields}
for field in opts.fields:
if field.name not in declared_fields_names :
perform_ddl(model_class, 'delete_column', table_name, field.name)
Hi,
In root README.MD you state that you are planning to drop the South dependency, this will actually drop support for django 1.6 and below.
Since this is an open source project, would you consider supporting both?
Here is a nice read about combining south & django 1.7 native "migrations"
http://treyhunner.com/2014/03/migrating-to-django-1-dot-7/
While it is quite simple to implement for most project it will not be a cake for this project as it makes extensive use of South.
But I`m sure it can be set.
Thanks.
This guide referenced in the README returns a 404
hello,
i'm using postgresql database.
I have created a new django project and at launch and when i'm trying to access my new admin i get:
Exception at /
<class 'mutant.models.field.FieldDefinition'> has more than 1 ForeignKey to <class 'mutant.models.model.ModelDefinition'>
Why ? anyone know ?
Ben.
I'm not sure if this is an actual issue, I wrote a simple crud interface using class based generic views, but the same issue happens from the admin interface as well. When the django devserver is started, and it registers the model classes, the dynamic models are not yet in AppCache. If I open a page, that lists all the available ModelDefinitions, like using the ListView:
class TableList(ListView):
model = models.ModelDefinition
And then using UpdateView I edit it:
class TableUpdate(UpdateView):
model = models.ModelDefinition
It works fine. Now if I restart the django server, and use the same link to open the UpdateView directly, without loading the list first, it will generate the modelform for it, I change only the name attribute, and after hitting save it fails, as the Model I edited was not registered in AppCache.
Traceback:
Environment:
Request Method: POST
Request URL: http://localhost:8000/tables/40/
Django Version: 1.4.2
Python Version: 2.6.8
Installed Applications:
('django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.admin',
'south',
'polymodels',
'mutant',
'mutant.contrib.boolean',
'mutant.contrib.temporal',
'mutant.contrib.file',
'mutant.contrib.numeric',
'mutant.contrib.text',
'mutant.contrib.web',
'mutant.contrib.related',
'schemer',
'debug_toolbar')
Installed Middleware:
('django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'debug_toolbar.middleware.DebugToolbarMiddleware')
Traceback:
File "/home/user/dev/virenvs/dynamicmodels/lib/python2.6/site-packages/django/core/handlers/base.py" in get_response
111. response = callback(request, *callback_args, **callback_kwargs)
File "/home/user/dev/virenvs/dynamicmodels/lib/python2.6/site-packages/django/views/generic/base.py" in view
48. return self.dispatch(request, *args, **kwargs)
File "/home/user/dev/virenvs/dynamicmodels/lib/python2.6/site-packages/django/views/generic/base.py" in dispatch
69. return handler(request, *args, **kwargs)
File "/home/user/dev/virenvs/dynamicmodels/lib/python2.6/site-packages/django/views/generic/edit.py" in post
195. return super(BaseUpdateView, self).post(request, *args, **kwargs)
File "/home/user/dev/virenvs/dynamicmodels/lib/python2.6/site-packages/django/views/generic/edit.py" in post
138. return self.form_valid(form)
File "/home/user/dev/virenvs/dynamicmodels/dynamodels/schemer/views.py" in form_valid
31. return super(TableUpdate, self).form_valid(form)
File "/home/user/dev/virenvs/dynamicmodels/lib/python2.6/site-packages/django/views/generic/edit.py" in form_valid
112. self.object = form.save()
File "/home/user/dev/virenvs/dynamicmodels/lib/python2.6/site-packages/django/forms/models.py" in save
364. fail_message, commit, construct=False)
File "/home/user/dev/virenvs/dynamicmodels/lib/python2.6/site-packages/django/forms/models.py" in save_instance
86. instance.save()
File "/home/user/dev/virenvs/dynamicmodels/lib/python2.6/site-packages/django_mutant-0.0.2-py2.6.egg/mutant/models/model/__init__.py" in save
230. save = super(ModelDefinition, self).save(*args, **kwargs)
File "/home/user/dev/virenvs/dynamicmodels/lib/python2.6/site-packages/django/db/models/base.py" in save
464. self.save_base(using=using, force_insert=force_insert, force_update=force_update)
File "/home/user/dev/virenvs/dynamicmodels/lib/python2.6/site-packages/django/db/models/base.py" in save_base
566. created=(not record_exists), raw=raw, using=using)
File "/home/user/dev/virenvs/dynamicmodels/lib/python2.6/site-packages/django/dispatch/dispatcher.py" in send
172. response = receiver(signal=self, sender=sender, **named)
File "/home/user/dev/virenvs/dynamicmodels/lib/python2.6/site-packages/django_mutant-0.0.2-py2.6.egg/mutant/management/__init__.py" in wrapper
53. **kwargs)
File "/home/user/dev/virenvs/dynamicmodels/lib/python2.6/site-packages/django_mutant-0.0.2-py2.6.egg/mutant/management/__init__.py" in model_definition_post_save
89. old_opts = instance._model_class._meta
Exception Type: AttributeError at /tables/40/
Exception Value: 'NoneType' object has no attribute '_meta'
Hi,
Before performing an add_column operation on the database, mutant prepare a native django field for south.
mutant\managment__init__.py:254
"field = instance._south_ready_field_instance()"
This field does not have its model attribute set.
This is ok in most cases but it should be set.
For example: trying to set a DateTimeField without a TimeZone while TimeZone support is active in settings will result in a warning.
See: django\db\models\fields__init__.py:903
The waning makes use of the model attribute for the django field create by _south_ready_field_instance.
This throws an exception...
Actually mutant.tests
uses mutant.contrib.text.CharFieldDefinition
and some other field definitions for it's core tests.
Some custom fields definitions should be created to test mutant core functionality instead of relying on contrib defined ones.
Hi!
I've created a simplest application that uses mutant (just made a project wuth django-admin startproject and added 'mutant' to INSTALLED_APPS).
However creating migrations produces this error:
# ./manage.py makemigrations
Traceback (most recent call last):
File "/usr/local/lib/python3.5/dist-packages/django/db/migrations/state.py", line 376, in from_model
clones = field.clone()
File "/usr/local/lib/python3.5/dist-packages/django/db/models/fields/__init__.py", line 458, in clone
return self.__class__(*args, **kwargs)
File "/usr/local/lib/python3.5/dist-packages/mutant/db/fields/generic.py", line 13, in __init__
'mutant.FieldDefinition', on_delete=on_delete, *args, **kwargs
TypeError: __init__() got multiple values for argument 'polymorphic_type'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "./manage.py", line 22, in <module>
execute_from_command_line(sys.argv)
File "/usr/local/lib/python3.5/dist-packages/django/core/management/__init__.py", line 367, in execute_from_command_line
utility.execute()
File "/usr/local/lib/python3.5/dist-packages/django/core/management/__init__.py", line 359, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/usr/local/lib/python3.5/dist-packages/django/core/management/base.py", line 294, in run_from_argv
self.execute(*args, **cmd_options)
File "/usr/local/lib/python3.5/dist-packages/django/core/management/base.py", line 345, in execute
output = self.handle(*args, **options)
File "/usr/local/lib/python3.5/dist-packages/django/core/management/commands/makemigrations.py", line 150, in handle
ProjectState.from_apps(apps),
File "/usr/local/lib/python3.5/dist-packages/django/db/migrations/state.py", line 188, in from_apps
model_state = ModelState.from_model(model)
File "/usr/local/lib/python3.5/dist-packages/django/db/migrations/state.py", line 384, in from_model
e,
TypeError: Couldn't reconstruct field content_type on mutant.FieldDefinition: __init__() got multiple values for argument 'polymorphic_type'
A quick look to the sources shows that PolymorphicTypeField.__init__
method has following signature (polymodels/fields.py, line 82):
def __init__(self, polymorphic_type, *args, **kwargs):
It is called from FieldDefinitionTypeField.__init__
method (mutant/db/fields/generic.py, line 11):
super(FieldDefinitionTypeField, self).__init__(
'mutant.FieldDefinition', on_delete=on_delete, *args, **kwargs
)
So 'mutant.FieldDefinition' is passed as 'polymorphic_type' parameter while kwargs dictionary also has 'polymorphic_type' key with value 'mutant.FieldDefinition', that causes the error.
Is it a bug or I missed anything in the configuration?
django-mutant: 0.2.1
django: 1.10.3
python: 3.5.2
--
Alexei
Unfortunately, documentation for this great application is currently missing and needs to be added to make it more user friendly (and useful) without reading through the source code.
The issue occurred for Integer, Float and Decimal fields surely, I haven't tested further, and only when using SQLite. PostgreSQL handles this fine. When creating a new field type, and a default value is not provided nor is the Null flag set to True, South raises an exception when it tries to create the db column. Here is the traceback:
Environment:
Request Method: POST
Request URL: http://localhost:8000/tables/43/fields/add/
Django Version: 1.4.2
Python Version: 2.6.8
Installed Applications:
('django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.admin',
'django.contrib.formtools',
'south',
'polymodels',
'mutant',
'mutant.contrib.boolean',
'mutant.contrib.temporal',
'mutant.contrib.file',
'mutant.contrib.numeric',
'mutant.contrib.text',
'mutant.contrib.web',
'mutant.contrib.related',
'schemer',
'debug_toolbar')
Installed Middleware:
('django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'debug_toolbar.middleware.DebugToolbarMiddleware')
Traceback:
File "/home/user/dev/virenvs/dynamicmodels/lib/python2.6/site-packages/django/core/handlers/base.py" in get_response
111. response = callback(request, *callback_args, **callback_kwargs)
File "/home/user/dev/virenvs/dynamicmodels/dynamodels/schemer/views.py" in field_create_wizard_view
209. return wizard(request, **kwargs)
File "/home/user/dev/virenvs/dynamicmodels/lib/python2.6/site-packages/django/views/generic/base.py" in view
48. return self.dispatch(request, *args, **kwargs)
File "/home/user/dev/virenvs/dynamicmodels/lib/python2.6/site-packages/django/contrib/formtools/wizard/views.py" in dispatch
223. response = super(WizardView, self).dispatch(request, *args, **kwargs)
File "/home/user/dev/virenvs/dynamicmodels/lib/python2.6/site-packages/django/views/generic/base.py" in dispatch
69. return handler(request, *args, **kwargs)
File "/home/user/dev/virenvs/dynamicmodels/lib/python2.6/site-packages/django/contrib/formtools/wizard/views.py" in post
286. return self.render_done(form, **kwargs)
File "/home/user/dev/virenvs/dynamicmodels/lib/python2.6/site-packages/django/contrib/formtools/wizard/views.py" in render_done
328. done_response = self.done(final_form_list, **kwargs)
File "/home/user/dev/virenvs/dynamicmodels/dynamodels/schemer/views.py" in done
201. ContentTypeModel.objects.create(**field_options)
File "/home/user/dev/virenvs/dynamicmodels/lib/python2.6/site-packages/django/db/models/manager.py" in create
137. return self.get_query_set().create(**kwargs)
File "/home/user/dev/virenvs/dynamicmodels/lib/python2.6/site-packages/django/db/models/query.py" in create
377. obj.save(force_insert=True, using=self.db)
File "/home/user/dev/virenvs/dynamicmodels/lib/python2.6/site-packages/django_mutant-0.0.2-py2.6.egg/mutant/models/field/__init__.py" in save
202. return super(FieldDefinition, self).save(*args, **kwargs)
File "/home/user/dev/virenvs/dynamicmodels/lib/python2.6/site-packages/django_polymodels-1.0.1-py2.6.egg/polymodels/models.py" in save
42. return super(BasePolymorphicModel, self).save(*args, **kwargs)
File "/home/user/dev/virenvs/dynamicmodels/lib/python2.6/site-packages/django_mutant-0.0.2-py2.6.egg/mutant/models/model/__init__.py" in save
251. save = super(ModelDefinitionAttribute, self).save(*args, **kwargs)
File "/home/user/dev/virenvs/dynamicmodels/lib/python2.6/site-packages/django/db/models/base.py" in save
463. self.save_base(using=using, force_insert=force_insert, force_update=force_update)
File "/home/user/dev/virenvs/dynamicmodels/lib/python2.6/site-packages/django/db/models/base.py" in save_base
565. created=(not record_exists), raw=raw, using=using)
File "/home/user/dev/virenvs/dynamicmodels/lib/python2.6/site-packages/django/dispatch/dispatcher.py" in send
172. response = receiver(signal=self, sender=sender, **named)
File "/home/user/dev/virenvs/dynamicmodels/lib/python2.6/site-packages/django_mutant-0.0.2-py2.6.egg/mutant/management/__init__.py" in wrapper
53. **kwargs)
File "/home/user/dev/virenvs/dynamicmodels/lib/python2.6/site-packages/django_mutant-0.0.2-py2.6.egg/mutant/management/__init__.py" in field_definition_post_save
208. instance.name, field, keep_default=keep_default)
File "/home/user/dev/virenvs/dynamicmodels/lib/python2.6/site-packages/django_mutant-0.0.2-py2.6.egg/mutant/management/__init__.py" in perform_ddl
34. getattr(db, action)(*args, **kwargs)
File "/home/user/dev/virenvs/dynamicmodels/lib/python2.6/site-packages/South-0.7.6-py2.6.egg/south/db/sqlite3.py" in add_column
25. raise ValueError("You cannot add a null=False column without a default value.")
Exception Type: ValueError at /tables/43/fields/add/
Exception Value: You cannot add a null=False column without a default value.
I am using multiple databases and database router. If I create a ModelDefinition or do anything which alter schema, the schema alteration is happening in all the databases instead of the current one.
Running the tests using django 1.5.1 and mutant 0.1.0 I get the following test failure:
$ python manage.py test mutant
Creating test database for alias 'default'...
...........................E................
======================================================================
ERROR: test_fixture_loading (mutant.tests.models.model.ModelDefinitionTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/peter/Code/envs/asdf/lib/python2.7/site-packages/mutant/tests/models/model.py", line 130, in test_fixture_loading
object_name='MyFixtureModel')
File "/Users/peter/Code/envs/asdf/lib/python2.7/site-packages/django/db/models/manager.py", line 143, in get
return self.get_query_set().get(*args, **kwargs)
File "/Users/peter/Code/envs/asdf/lib/python2.7/site-packages/django/db/models/query.py", line 389, in get
(self.model._meta.object_name, kwargs))
DoesNotExist: ModelDefinition matching query does not exist. Lookup parameters were {'object_name': u'MyFixtureModel', 'app_label': u'myfixtureapp'}
----------------------------------------------------------------------
Ran 44 tests in 3.642s
FAILED (errors=1)
I'm trying to serializing ModelDefinition using DRF. I can create model record in mutant_modeldefinition. But the table related was not created. Any one knows why?
hi charettes:
I use the following code to define my dynamic model
from mutant.contrib.text.models import CharFieldDefinition
from mutant.models.model import ModelDefinition
def home_view(request):
model_def = ModelDefinition.objects.create(
app_label='app',
object_name='MyOtherModel',
)
char_field = CharFieldDefinition.objects.create(
name='char_field',
max_length=25,
model_def=model_def
)
OtherModel = model_def.model_class()
OtherModel.objects.create(char_field='hello world')
queryset = OtherModel.objects.all()
d = serializers.serialize('json',queryset)
return HttpResponse(d)
it gives the UNIQUE constraint failed
but when I set app_label='mutant' ,it works fine.
Does app_label need hard coded?
hi charettes
I read https://gist.github.com/charettes/5670245 and to run it, when code to
ForeignKeyDefinition.objects.create(
model_def=street_model_def, name='city', to=city_model_def.model_class()
)
it go exception
"ForeignKeyDefinition.to" must be a "ContentType" instance.
I use django 1.9.7 and python 2.7
it seems the 'to' paramter is wrong ,I change to=city_model_def and it works
BTW,how to add self related foreignkey field?
when I register field on admin page it make the project crash.
AttributeError: 'module' object has no attribute 'FieldDefinition'
Performing system checks...
Unhandled exception in thread started by <function wrapper at 0x103b555f0>
Traceback (most recent call last):
File "/Users/caoguangyao/Desktop/venv/lib/python2.7/site-packages/django/utils/autoreload.py", line 226, in wrapper
fn(*args, **kwargs)
File "/Users/caoguangyao/Desktop/venv/lib/python2.7/site-packages/django/core/management/commands/runserver.py", line 116, in inner_run
self.check(display_num_errors=True)
File "/Users/caoguangyao/Desktop/venv/lib/python2.7/site-packages/django/core/management/base.py", line 472, in check
raise SystemCheckError(msg)
django.core.management.base.SystemCheckError: SystemCheckError: System check identified some issues:
ERRORS:
dynamic.TagTree.parent: (fields.E302) Reverse accessor for 'TagTree.parent' clashes with field name 'TagTree.parent'.
HINT: Rename field 'TagTree.parent', or add/change a related_name argument to the definition for field 'TagTree.parent'.
dynamic.TagTree.parent: (fields.E303) Reverse query name for 'TagTree.parent' clashes with field name 'TagTree.parent'.
HINT: Rename field 'TagTree.parent', or add/change a related_name argument to the definition for field 'TagTree.parent'.
System check identified 2 issues (0 silenced).
I cannot restore fixtures on dynamic models created with manage.py dumpdata
.
To test this I've created a small django project as failure test case named mutfix_proj.
Here you are my project files:
mutfix_proj/mutfix_proj/settings.py:
....
DATABASES = {
'default': {
'ENGINE': 'django.contrib.gis.db.backends.postgis',
'NAME': 'mutfix_db',
'USER': 'mutfix_usr',
'PASSWORD': 'mutfix',
'HOST': 'localhost',
'PORT': '5432',
}
}
...
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.staticfiles',
'django.contrib.gis',
'south',
'polymodels',
'mutant',
'mutant.contrib.geo',
'mutant.contrib.numeric',
'mutant.contrib.text',
# To get the possibility to make spatial_ref_sys ForeignKey
'django.contrib.gis.db.backends.postgis',
'mutfix_test',
)
...
mutfix_proj/mutfix_test/models.py:
from django.db import models
from django.contrib.gis.models import SpatialRefSys
from mutant.models import ModelDefinition
class ShapeFile(models.Model):
name = models.SlugField()
srid = models.ForeignKey(SpatialRefSys)
mutant_table_1 = models.ForeignKey(ModelDefinition, null=True, related_name='mutant_table_1')
mutant_table_2 = models.ForeignKey(ModelDefinition, null=True, related_name='mutant_table_2')
mutfix_proj/mutfix_test/views.py:
from models import *
from mutant.models import *
from mutant.contrib.geo.models import *
from mutant.contrib.numeric.models import *
from mutant.contrib.text.models import *
from django.contrib.gis.models import SpatialRefSys
from django.contrib.gis.geos import GEOSGeometry
def createDifferentFieldTables():
sridVal = 31256
projObj = SpatialRefSys.objects.get(pk=sridVal)
# Save it once to obtain shapefile id:
# I need it to name the test table
obj = ShapeFile(name='test', srid=projObj)
obj.save()
# The final table name is something like 'mutant_mutfix_123_test'
table_name_1 = str(obj.id) + '_test_1'
table_name_2 = str(obj.id) + '_test_2'
# Creates a table, otherwise return the retrieved one
model_def_1, created = ModelDefinition.objects.get_or_create(
app_label='mutfix_test',
object_name=table_name_1,
defaults=dict(
bases=(BaseDefinition(base=GeoModel),),
fields=(GeometryFieldDefinition(name='the_geom', srid=sridVal),
SmallIntegerFieldDefinition(name='cat'),)
)
)
model_def_2, created = ModelDefinition.objects.get_or_create(
app_label='mutfix_test',
object_name=table_name_2,
defaults=dict(
bases=(BaseDefinition(base=GeoModel),),
fields=(GeometryFieldDefinition(name='the_geom', srid=sridVal),
CharFieldDefinition(name='fun_name', max_length=30),
SmallIntegerFieldDefinition(name='step'),
SmallIntegerFieldDefinition(name='cat'),)
)
)
obj.mutant_table_1 = model_def_1
obj.mutant_table_2 = model_def_2
# Update the object with mutant table
obj.save()
After manage.py syncdb
, I've opened a django shell with manage.py shell
and performed:
>>> from mutfix_test.views import createDifferentFieldTables
>>> createDifferentFieldTables()
In this way I got my dynamic tables. After that I used
./manage.py dumpdata --natural --indent 2 contenttypes mutant mutfix_test
to obtain the fixture file: mutfix_proj/mutfix_test/fixture/initial_data.json
I've dropped my db with dropdb mutfix_db
as postgres user, recreated it using createdb -O mutfix_usr mutfix_db ; psql -U mutfix_usr mutfix_db
and inside postgresql shellCREATE EXTENSION postgis; \q
.
Next I used manage.py syncdb
to restore my project tables, adding as initial data my fixtures.
Unfortunately it gives me the following error:
DoesNotExist: Problem installing fixture '/home/usr/mutfix_proj/mutfix_test/fixtures/initial_data.json': ModelDefinition matching query does not exist.
I've inspected mutant tables created and filled with createDifferentFieldTables()
and with my fixture to see the differences (I made a comparison following the fixture table order): contenttypes.contenttype, mutant.modeldefinition and mutant.basedefinition are filled correctly.
Problems start with mutant.basedefinition, which is completely empty in fixture case but with 6 element using my test function...and it's the same with every other mutant table. Dynamic tables mutant_mutfix_test_1_test_1 and mutant_mutfix_test_1_test_2 are created, but only with the id field, I think due to previous errors.
How to solve this?
Hope to be helpful in this amazing project.
Thank you.
EDIT: in fixture file, base field inside mutant.basedefinition and default field inside mutant.fielddefinitions are different: for example the real value of mutant.basedefinition.base with pk==1 should be
gAJjcGlja2xlZmllbGQuZmllbGRzCl9PYmplY3RXcmFwcGVyCnEBKYFxAk59cQNVBF9vYmpxBGNtdXRhbnQuY29udHJpYi5nZW8ubW9kZWxzLm1vZGVsCkdlb01vZGVsCnEFc4ZiLg==
and instead inside fixture is
gAJjbXV0YW50LmNvbnRyaWIuZ2VvLm1vZGVscy5tb2RlbApHZW9Nb2RlbApxAS4=
mutant/contrib/related/models.py
RelatedFieldDefinition's clean method calls self.to_model_class_is_mutable:
def clean(self):
if (self.related_name is not None and
not self.to_model_class_is_mutable):
msg = _('Cannot assign a related manager to non-mutable model')
raise ValidationError({'related_name': [msg]})
Which upon calling self.to.model_class() raises DoesNotExist in cases when the "to" field
was left empty, which may be the correct behavior, but I thought it will be catched and a
ValidationError will be raised.
@property
def to_model_class_is_mutable(self):
to_model_class = self.to.model_class()
if to_model_class is None:
try:
getattr(self.to, 'modeldefinition')
except ModelDefinition.DoesNotExist:
return False
else:
return True
else:
return issubclass(to_model_class, MutableModel)
Sorry if that was not your intention, it's solvable with a workaround in form validation, I just
thought it should work differently.
Hi, unfortunately I am getting the error that I am missing the queryset.
Not really sure what is going on here, hope you can help.
Please find the traceback below
Environment:
Request Method: GET
Request URL: http://127.0.0.1:8000/tables/38/fields/create/?field_type=32
Django Version: 2.1
Python Version: 3.6.4
Installed Applications:
['django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.sites',
'testapp',
'mutant',
'mutant.contrib.boolean',
'mutant.contrib.temporal',
'mutant.contrib.file',
'mutant.contrib.numeric',
'mutant.contrib.text',
'mutant.contrib.web',
'mutant.contrib.related',
'polymodels']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware']
Traceback:
File "C:\Users\Jan-Paul\Desktop\test\lib\site-packages\django\core\handlers\exception.py" in inner
34. response = get_response(request)
File "C:\Users\Jan-Paul\Desktop\test\lib\site-packages\django\core\handlers\base.py" in _get_response
126. response = self.process_exception_by_middleware(e, request)
File "C:\Users\Jan-Paul\Desktop\test\lib\site-packages\django\core\handlers\base.py" in _get_response
124. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\Jan-Paul\Desktop\test\lib\site-packages\django\views\generic\base.py" in view
68. return self.dispatch(request, *args, **kwargs)
File "C:\Users\Jan-Paul\Desktop\test\lib\site-packages\django\views\generic\base.py" in dispatch
88. return handler(request, *args, **kwargs)
File "C:\Users\Jan-Paul\Desktop\test\testproject\testapp\views.py" in get
123. return self._prepare_dynamic_form(request, table_pk, super_func)
File "C:\Users\Jan-Paul\Desktop\test\testproject\testapp\views.py" in _prepare_dynamic_form
112. self.form_class = get_field_def_form(field_type_pk, model_defs)
File "C:\Users\Jan-Paul\Desktop\test\testproject\testapp\forms.py" in get_field_def_form
22. 'content_type': FieldDefinitionTypeField(widget=forms.HiddenInput),
File "C:\Users\Jan-Paul\Desktop\test\lib\site-packages\mutant\forms.py" in __init__
61. super(FieldDefinitionTypeField, self).__init__(*args, **kwargs)
Exception Type: TypeError at /tables/38/fields/create/
Exception Value: __init__() missing 1 required positional argument: 'queryset'
and the form.py in my app
from django import forms
from mutant.forms import FieldDefinitionTypeField
from testapp.utils import FIELD_TYPES, get_mutant_type
class AddFieldForm(forms.Form):
field_type = forms.ChoiceField(choices=FIELD_TYPES)
def clean_field_type(self):
return int(self.cleaned_data['field_type'])
def get_field_def_form(field_type_pk, model_def_queryset):
class Meta:
model = get_mutant_type(field_type_pk)
form_attrs = {
'Meta': Meta,
'content_type': FieldDefinitionTypeField(widget=forms.HiddenInput),
'model_def': forms.ModelChoiceField(queryset=model_def_queryset,
widget=forms.HiddenInput)
}
return type('FieldDefinitionForm', (forms.ModelForm,), form_attrs)
I have installed django-mutant and performed CRUD operations on Table Definition, Field Definitions and on Dynamically created models. But when I try to do migration after the above operations it returns TypeError in mutant.FieldDefinition. Below is the traceback
python onboard/manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, boolean, contenttypes, file, mutant, numeric, related, sessions, temporal, text, web
Running migrations:
No migrations to apply.
Traceback (most recent call last):
File "/media/sathish/Study/Office/django-onboard/venv/lib/python3.4/site-packages/django/db/migrations/state.py", line 411, in from_model
fields.append((name, field.clone()))
File "/media/sathish/Study/Office/django-onboard/venv/lib/python3.4/site-packages/django/db/models/fields/__init__.py", line 470, in clone
return self.__class__(*args, **kwargs)
File "/media/sathish/Study/Office/django-onboard/venv/lib/python3.4/site-packages/mutant/db/fields/generic.py", line 12, in __init__
'mutant.FieldDefinition', on_delete=on_delete, *args, **kwargs
TypeError: __init__() got multiple values for argument 'polymorphic_type'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "onboard/manage.py", line 15, in <module>
execute_from_command_line(sys.argv)
File "/media/sathish/Study/Office/django-onboard/venv/lib/python3.4/site-packages/django/core/management/__init__.py", line 371, in execute_from_command_line
utility.execute()
File "/media/sathish/Study/Office/django-onboard/venv/lib/python3.4/site-packages/django/core/management/__init__.py", line 365, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/media/sathish/Study/Office/django-onboard/venv/lib/python3.4/site-packages/django/core/management/base.py", line 288, in run_from_argv
self.execute(*args, **cmd_options)
File "/media/sathish/Study/Office/django-onboard/venv/lib/python3.4/site-packages/django/core/management/base.py", line 335, in execute
output = self.handle(*args, **options)
File "/media/sathish/Study/Office/django-onboard/venv/lib/python3.4/site-packages/django/core/management/commands/migrate.py", line 180, in handle
ProjectState.from_apps(apps),
File "/media/sathish/Study/Office/django-onboard/venv/lib/python3.4/site-packages/django/db/migrations/state.py", line 222, in from_apps
model_state = ModelState.from_model(model)
File "/media/sathish/Study/Office/django-onboard/venv/lib/python3.4/site-packages/django/db/migrations/state.py", line 416, in from_model
e,
TypeError: Couldn't reconstruct field content_type on mutant.FieldDefinition: __init__() got multiple values for argument 'polymorphic_type'
Hi charettes,
when i use
python manage.py makemigrations
it get an error about
TypeError: Couldn't reconstruct field content_type on mutant.FieldDefinition: init() got multiple values for keyword argument 'polymorphic_type'
How do I deal with it?
python manage.py schemamigration app_name --init
Traceback (most recent call last):
File "manage.py", line 10, in <module>
execute_from_command_line(sys.argv)
File ".../local/lib/python2.7/site-packages/django/core/management/__init__.py", line 399, in execute_from_command_line
utility.execute()
File ".../local/lib/python2.7/site-packages/django/core/management/__init__.py", line 392, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File ".../local/lib/python2.7/site-packages/django/core/management/base.py", line 242, in run_from_argv
self.execute(*args, **options.__dict__)
File ".../local/lib/python2.7/site-packages/django/core/management/base.py", line 285, in execute
output = self.handle(*args, **options)
File ".../local/lib/python2.7/site-packages/south/management/commands/schemamigration.py", line 151, in handle
for action_name, params in change_source.get_changes():
File ".../local/lib/python2.7/site-packages/south/creator/changes.py", line 460, in get_changes
model_defs = freeze_apps([self.migrations.app_label()])
File ".../local/lib/python2.7/site-packages/south/creator/freezer.py", line 37, in freeze_apps
model_defs[model_key(model)] = prep_for_freeze(model)
File ".../local/lib/python2.7/site-packages/south/creator/freezer.py", line 73, in prep_for_freeze
fields = modelsinspector.get_model_fields(model, m2m=True)
File ".../local/lib/python2.7/site-packages/south/modelsinspector.py", line 413, in get_model_fields
args, kwargs = introspector(field)
File ".../local/lib/python2.7/site-packages/south/modelsinspector.py", line 373, in introspector
kwargs[kwd] = get_value(field, defn)
File ".../local/lib/python2.7/site-packages/south/modelsinspector.py", line 292, in get_value
return value_clean(value, options)
File ".../local/lib/python2.7/site-packages/south/modelsinspector.py", line 350, in value_clean
value = options['converter'](value)
File ".../local/lib/python2.7/site-packages/south/modelsinspector.py", line 54, in convert_on_delete_handler
raise ValueError("%s was not recognized as a valid model deletion handler. Possible values: %s." % (value, ', '.join(f.__name__ for f in (models.CASCADE, models.PROTECT, models.SET, models.SET_NULL, models.SET_DEFAULT, models.DO_NOTHING))))
ValueError: <function CASCADE_MARK_ORIGIN at 0x1cfc758> was not recognized as a valid model deletion handler. Possible values: CASCADE, PROTECT, SET, set_on_delete, SET_DEFAULT, DO_NOTHING.
Found that the problem occurs when trying to create a South migration scheme for ModelDefinitionAttribute.
Please, help solve this problem.
When trying to restore a fixture with a non-mutable base it's not wrapped in an ObjectWrapper thus exposing it's prepare_database_save
instance method to getattr
checks and failing to be called from the class context.
Hi,
Im not sure of this, but I would point it anyway, feel free to correct me and explain if you can.
On mutant.models.model.MutableModelProxy the instantiation (new) should return the new object for initialization.
In line 79 there is a call to init with the new object (proxy)
line 80 returns the new object...
Python then calls the init again, as part of natural object creation process.
"self" has the same reference address in both calls (inside init)
Is it a deliberate behavior? is so, can you please explain why?
Thanks.
I'm attempting to create a M2M field to the User model using ManyToManyFieldDefinition. I am able to add the field without error:
ManyToManyFieldDefinition.objects.create(model_def=author_model_def, name='friends', to=ContentType.objects.get_for_model(User), null=True, blank=True)
Here is my full code example creating a model with a couple CharFields, a FK field and a M2M field.
from core.models import *
from mutant.models import ModelDefinition
from mutant.contrib.text.models import CharFieldDefinition
from django.contrib.contenttypes.models import ContentType
from mutant.contrib.related.models import ForeignKeyDefinition, ManyToManyFieldDefinition
author_model_def = ModelDefinition.objects.create(app_label='core', object_name='Author')
CharFieldDefinition.objects.create(model_def=author_model_def, name='name', max_length=50)
Author = author_model_def.model_class()
a1= Author.objects.create(name='Joe Blow')
CharFieldDefinition.objects.create(model_def=author_model_def, name='age', max_length=4, default='30')
ForeignKeyDefinition.objects.create(model_def=author_model_def, name='user', to=ContentType.objects.get_for_model(User), null=True, blank=True)
ManyToManyFieldDefinition.objects.create(model_def=author_model_def, name='friends', to=ContentType.objects.get_for_model(User), null=True, blank=True)
a2 = Author.objects.create(name="Steve")
a2.friends.add(User.objects.get(pk=1))
All of the above code works except the last line. In attempting to add a M2M relation, the following traceback results:
using SQLite db:
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "C:\Users\Steve\StevesFolder\Programming\bpa\bpa_env\lib\site-packages\django\db\models\fields\related.py", line 650, in add
self._add_items(self.source_field_name, self.target_field_name, *objs)
File "C:\Users\Steve\StevesFolder\Programming\bpa\bpa_env\lib\site-packages\django\db\models\fields\related.py", line 725, in _add_items
new_ids = new_ids - set(vals)
File "C:\Users\Steve\StevesFolder\Programming\bpa\bpa_env\lib\site-packages\django\db\models\query.py", line 123, in _result_iter
self._fill_cache()
File "C:\Users\Steve\StevesFolder\Programming\bpa\bpa_env\lib\site-packages\django\db\models\query.py", line 927, in _fill_cache
self._result_cache.append(next(self._iter))
File "C:\Users\Steve\StevesFolder\Programming\bpa\bpa_env\lib\site-packages\django\db\models\query.py", line 1126, in iterator
for row in self.query.get_compiler(self.db).results_iter():
File "C:\Users\Steve\StevesFolder\Programming\bpa\bpa_env\lib\site-packages\django\db\models\sql\compiler.py", line 775, in results_iter
for rows in self.execute_sql(MULTI):
File "C:\Users\Steve\StevesFolder\Programming\bpa\bpa_env\lib\site-packages\django\db\models\sql\compiler.py", line 840, in execute_sql
cursor.execute(sql, params)
File "C:\Users\Steve\StevesFolder\Programming\bpa\bpa_env\lib\site-packages\django\db\backends\util.py", line 41, in execute
return self.cursor.execute(sql, params)
File "C:\Users\Steve\StevesFolder\Programming\bpa\bpa_env\lib\site-packages\django\db\backends\sqlite3\base.py", line 366, in execute
six.reraise(utils.DatabaseError, utils.DatabaseError(*tuple(e.args)), sys.exc_info()[2])
File "C:\Users\Steve\StevesFolder\Programming\bpa\bpa_env\lib\site-packages\django\db\backends\sqlite3\base.py", line 362, in execute
return Database.Cursor.execute(self, query, params)
DatabaseError: no such table: mutant_core_author_friends
and using Postgres:
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "C:\Users\Steve\StevesFolder\Programming\bpa\bpa_env\lib\site-packages\django\db\models\fields\related.py", line 650, in add
self._add_items(self.source_field_name, self.target_field_name, *objs)
File "C:\Users\Steve\StevesFolder\Programming\bpa\bpa_env\lib\site-packages\django\db\models\fields\related.py", line 725, in _add_items
new_ids = new_ids - set(vals)
File "C:\Users\Steve\StevesFolder\Programming\bpa\bpa_env\lib\site-packages\django\db\models\query.py", line 123, in _result_iter
self._fill_cache()
File "C:\Users\Steve\StevesFolder\Programming\bpa\bpa_env\lib\site-packages\django\db\models\query.py", line 927, in _fill_cache
self._result_cache.append(next(self._iter))
File "C:\Users\Steve\StevesFolder\Programming\bpa\bpa_env\lib\site-packages\django\db\models\query.py", line 1126, in iterator
for row in self.query.get_compiler(self.db).results_iter():
File "C:\Users\Steve\StevesFolder\Programming\bpa\bpa_env\lib\site-packages\django\db\models\sql\compiler.py", line 775, in results_iter
for rows in self.execute_sql(MULTI):
File "C:\Users\Steve\StevesFolder\Programming\bpa\bpa_env\lib\site-packages\django\db\models\sql\compiler.py", line 840, in execute_sql
cursor.execute(sql, params)
File "C:\Users\Steve\StevesFolder\Programming\bpa\bpa_env\lib\site-packages\django\db\backends\util.py", line 41, in execute
return self.cursor.execute(sql, params)
File "C:\Users\Steve\StevesFolder\Programming\bpa\bpa_env\lib\site-packages\django\db\backends\postgresql_psycopg2\base.py", line 58, in execute
six.reraise(utils.DatabaseError, utils.DatabaseError(*tuple(e.args)), sys.exc_info()[2])
File "C:\Users\Steve\StevesFolder\Programming\bpa\bpa_env\lib\site-packages\django\db\backends\postgresql_psycopg2\base.py", line 54, in execute
return self.cursor.execute(query, args)
DatabaseError: relation "mutant_core_author_friends" does not exist
LINE 1: ...ELECT "mutant_core_author_friends"."user_id" FROM "mutant_co...
Am I missing something in my declaration of the M2M field that is preventing the table from being created?
Dear charettes,
your dependency to django-orderable is not working. You are not using the django-orderable package witch is on pip-index. So in your requirements described with "django-orderable", it will take the wrong one.
This happens since dependency_links for pip are deprecated (http://serverfault.com/questions/608192/pip-install-seems-to-be-ignoring-dependency-links).
I guess, a good solution would be to put the link to django-orderable on git directly in your requirements.
Thanks for developing on this project :)
Regards
Per Fuchs
Hi,
I'm using Django-Mutant in my project and when trying to create a ManyToMany Field the following Error occurs:
File "C:\Python34\lib\site-packages\django\db\backends\base\schema.py", line 3
81, in add_field
if field.many_to_many and field.remote_field.through._meta.auto_created:
AttributeError: 'NoneType' object has no attribute '_meta'
The error indicates that field.remote_field.through attribute does not exist which it does not.
I'm using the following code to create a ManyToMany Field
fieldl,created= ManyToManyFieldDefinition.objects.update_or_create(model_def=model, name=field.FieldName+str(field.id), to=related_ct, null=True, blank=True)
When I debug the data it looks ok:
(Pdb) args
self = <ManyToManyFieldDefinition: ManyToManyFieldDefinition object>
args = ()
kwargs = {'to': <ContentType: task def>, 'blank': True, 'name': 'Field290', 'mod
el_def': <ModelDefinition: resources.resource5>, 'null': True}
Am i missing something or mutant and Django 1.9.5 just don't play well.
Thanks,
Ivica
Hi, I'm following the example https://github.com/integricho/mutant-sample-app with Django 1.10 and I have this error in FieldCreateView:
init() takes at least 2 arguments (2 given)
trace resume:
/home/tony/projetos/xy-inc/src/sistema/views.py in get
super_func = lambda: super(CampoCriaView, self).get(request, modelo_pk) ...
▶ Local vars
/home/tony/projetos/xy-inc/src/sistema/views.py in _prepare_dynamic_form
self.form_class = get_field_def_form(field_type_pk, model_defs) ...
▶ Local vars
/home/tony/projetos/xy-inc/src/sistema/forms.py in get_field_def_form
'content_type': FieldDefinitionTypeField(widget=forms.HiddenInput), ...
▶ Local vars
/home/tony/projetos/.virtualenvs/xyinc/local/lib/python2.7/site-packages/mutant/forms.py in __init__
super(FieldDefinitionTypeField, self).__init__(*args, **kwargs) ...
▶ Local vars
my view:
class CampoCriaView(SuccessUrlMixin, CreateView):
template_name = 'sistema/salvar_campo.html'
fields = '__all__'
def __init__(self, *args, **kwargs):
super(CampoCriaView, self).__init__(*args, **kwargs)
def get_success_url(self):
self.success_url = self.get_reversed_success_url()
return super(CampoCriaView, self).get_success_url()
def _prepare_dynamic_form(self, request, modelo_pk, super_func):
form = AddFieldForm(request.GET)
if form.is_valid():
field_type_pk = form.cleaned_data['field_type']
modelo_pk = self.kwargs.get('modelo_pk', None)
model_defs = models.ModelDefinition.objects.filter(pk=modelo_pk)
self.form_class = get_field_def_form(field_type_pk, model_defs)
self.model = get_mutant_type(field_type_pk)
self.initial = {'model_def': modelo_pk,
'content_type': field_type_pk}
retorno = super_func()
return retorno
else:
return redirect(self.get_success_url())
def get(self, request, modelo_pk):
super_func = lambda: super(CampoCriaView, self).get(request, modelo_pk)
return self._prepare_dynamic_form(request, modelo_pk, super_func)
def post(self, request, modelo_pk):
super_func = lambda: super(CampoCriaView, self).post(request, modelo_pk)
return self._prepare_dynamic_form(request, modelo_pk, super_func)
I really need help, thanks!
I add a static model and do some change in my models.py
After I run
python manage.py migrate --fake-initial
the command
python manage.py makemigrations
does not work ,and throws the exception:
TypeError: Couldn't reconstruct field content_type on mutant.FieldDefinition: init() got multiple values for keyword argument 'polymorphic_type'
how do I re-sync my database?
When performing multiple FieldDefinition
additions and removals many queries are executed to force the creation of the most up-to-date model definition through model_def.model_class(force_create=True)
calls.
In order to reduce the number of queries executed we could prevent those reflows with a context manager:
with model_def.prevent_reflows(): # TODO: Find a better method name
# The following queries would issue only ALTER, DROP statements and not re-flows
# of the model_class associated with the model_def.
model_def_first_field.delete()
model_def_char_field.max_length = 34
model_def_char_field.save()
# One re-flow would happen when exiting the context manager.
Hi !!
It is more than a question that an issue.
Is it possible to use django-mutant
with django rest_framework
?
Indeed, I tried to connect a mutant model with a ModelViewSet
and ModelSerializer
. It works perfectly. But If I add a new field, I need to restart all the django app in order to see the new field in the next request (e.g : from postman).
I tried lot of aproach
Edit :
I saw that even if I subclass the ModelViewSet and ModelSerializer in order to have a dynamic model, the _meta
object inside the model is always the same. (Lot of DRF stuff use _meta
in order to get fields...)
Quick and dirty test inside a viewset class:
# Inside TempViewSet wich inherit of viewsets.ModelViewSet
def list(self, *args, **kwargs):
ct = ModelDefinition.objects.get(object_name="awesome")
ct_class = ct.model_class()
print(id(ct_class)) # Always a different object
print(id(ct_class._meta)) # Always the same object
self.queryset = ct_class.objects.all()
return super(TempViewSet, self).list(*args, **kwargs)
When I am in the django shell, all works well:
>>> ct = ModelDefinition.objects.get(model='awesome')
>>> id(ct.model_class()._meta)
>>> 140283303675264
>>> CharFieldDefinition.objects.create(model_def=ct, name='good', max_length=50, null=True, blank=True)
>>> <CharFieldDefinition: CharFieldDefinition object (33)>
>>> id(ct.model_class()._meta)
>>> 140283303675120
I am run out of ideas :/
Any help will be very usefull !
Best regards from France,
Provide an API to replace a field definition type by using south's alter_column.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.