django ValueError when loading JSON fixture with many-to-many relationships - python

I am building a website with django/python. The website database I am building contains books, and I am trying to relate Character objects to Event objects by defining their relationships in the fixture. I load my fixtures from .json files using
loaddata fixtures <file>
This works for my models that have no relationships, but when I try to load a fixture that contains many-to-many relationships (characters appear in many events, events contain many characters) I get the following :
ValueError: Problem installing fixture: < file path >: "< Character: Lanoree Brock > " needs to have a value for field "character" before this many-to-many relationship can be used.
There is no field "character" in my model for Character:
class Character(models.Model):
id = models.IntegerField(primary_key = True)
name = models.CharField(max_length = ml)
bio = models.TextField()
event = models.ManyToManyField(Event)
def __str__(self):
return self.name
class Meta:
ordering = ('name',)
The .json file for my Character fixture looks like this:
[{"model": "library.Character", "id": 1,
"fields": {"name": "Lanoree Brock", "bio": "He lived", "event": [101, 102, ...]}}
... ]
So the error occurs at the first Character. My guess as to the problem is that django tries to add the relationship to the < Character: Lanoree Brock > object before it saves the object, but I do not understand why it is doing that or how to get around it.
Is there a way to structure the fixture to ensure that when it is loaded each object is created/saved before the code tries to define its relationships?
I am new to django, JSON syntax, and web dev in general, and I feel like there's something simple I'm not doing here -- if fixtures cannot handle many-to-many relationships, that seems like a huge oversight in their functionality.
Any help would be appreciated, thank you!
Edit: The full error log:
Traceback (most recent call last):
File "manage.py", line 10, in <module>
execute_from_command_line(sys.argv)
File "c:\Users\MetalGearSamus\Anaconda\lib\site-packages\django\core\managemen
t\__init__.py", line 353, in execute_from_command_line
utility.execute()
File "c:\Users\MetalGearSamus\Anaconda\lib\site-packages\django\core\managemen
t\__init__.py", line 345, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "c:\Users\MetalGearSamus\Anaconda\lib\site-packages\django\core\managemen
t\base.py", line 348, in run_from_argv
self.execute(*args, **cmd_options)
File "c:\Users\MetalGearSamus\Anaconda\lib\site-packages\django\core\managemen
t\base.py", line 399, in execute
output = self.handle(*args, **options)
File "c:\Users\MetalGearSamus\Anaconda\lib\site-packages\django\core\managemen
t\commands\loaddata.py", line 60, in handle
self.loaddata(fixture_labels)
File "c:\Users\MetalGearSamus\Anaconda\lib\site-packages\django\core\managemen
t\commands\loaddata.py", line 100, in loaddata
self.load_label(fixture_label)
File "c:\Users\MetalGearSamus\Anaconda\lib\site-packages\django\core\managemen
t\commands\loaddata.py", line 158, in load_label
obj.save(using=self.using)
File "c:\Users\MetalGearSamus\Anaconda\lib\site-packages\django\core\serialize
rs\base.py", line 204, in save
setattr(self.object, accessor_name, object_list)
File "c:\Users\MetalGearSamus\Anaconda\lib\site-packages\django\db\models\fiel
ds\related_descriptors.py", line 480, in __set__
manager = self.__get__(instance)
File "c:\Users\MetalGearSamus\Anaconda\lib\site-packages\django\db\models\fiel
ds\related_descriptors.py", line 468, in __get__
return self.related_manager_cls(instance)
File "c:Users\MetalGearSamus\Anaconda\lib\site-packages\django\db\models\fiel
ds\related_descriptors.py", line 751, in __init__
(instance, self.source_field_name))
ValueError: Problem installing fixture 'c:Users\MetalGearSamus\Personal\Legends\website\library\fixtures\database.json': "<Character: Lanoree Brock>" needs to
have a value for field "character" before this many-to-many relationship can be
used.

Related

Connect to another database and dumpdata from it in json format

My task is to populate my two existing City and Province model using two json files cities.json' and 'provinces.json.
Data in these files are as below.
provinces.json:
[
{ "model": "salesnetwork.provinces",
"id": "1",
"name": "EA"
}
]
cities.json:
[
{ "model": "salesnetwork.cities",
"id": "1",
"province_id": "1",
"name": "Tabriz"
}
]
Now I'm trying to poplulate my two models with these data. My models are as below.
class Provinces(models.Model):
name = models.CharField(max_length=255, db_collation="utf8mb3_unicode_ci")
class Meta:
db_table = "provinces"
class Cities(models.Model):
province = models.ForeignKey("Provinces", models.DO_NOTHING)
name = models.CharField(max_length=255, db_collation="utf8mb3_unicode_ci")
class Meta:
db_table = "cities"
(My bad for naming my model Cities instead of City and Provinces instead of 'Province'; I've created these models via inspectdb command and since I didn't know if changing these model names could cause problems or not, I decided to leave the names as they were).
When I try using command py .\manage.py loaddata provinces.json I get the following error:
Traceback (most recent call last):
File "D:\Projects\Navid Motor\Website\Django\NavidMotor.com\.venv\lib\site-packages\django\core\serializers\json.py", line 69, in Deserializer
objects = json.loads(stream_or_string)
File "C:\Users\Vahid Moradi\AppData\Local\Programs\Python\Python310\lib\json\__init__.py", line 335, in loads
raise JSONDecodeError("Unexpected UTF-8 BOM (decode using utf-8-sig)",
json.decoder.JSONDecodeError: Unexpected UTF-8 BOM (decode using utf-8-sig): line 1 column 1 (char 0)
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "D:\Projects\Navid Motor\Website\Django\NavidMotor.com\manage.py", line 22, in <module>
main()
File "D:\Projects\Navid Motor\Website\Django\NavidMotor.com\manage.py", line 18, in main
execute_from_command_line(sys.argv)
File "D:\Projects\Navid Motor\Website\Django\NavidMotor.com\.venv\lib\site-packages\django\core\management\__init__.py", line 446, in execute_from_command_line
utility.execute()
File "D:\Projects\Navid Motor\Website\Django\NavidMotor.com\.venv\lib\site-packages\django\core\management\__init__.py", line 440, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "D:\Projects\Navid Motor\Website\Django\NavidMotor.com\.venv\lib\site-packages\django\core\management\base.py", line 402, in run_from_argv
self.execute(*args, **cmd_options)
File "D:\Projects\Navid Motor\Website\Django\NavidMotor.com\.venv\lib\site-packages\django\core\management\base.py", line 448, in execute
output = self.handle(*args, **options)
File "D:\Projects\Navid Motor\Website\Django\NavidMotor.com\.venv\lib\site-packages\django\core\management\commands\loaddata.py", line 102, in handle
self.loaddata(fixture_labels)
File "D:\Projects\Navid Motor\Website\Django\NavidMotor.com\.venv\lib\site-packages\django\core\management\commands\loaddata.py", line 163, in loaddata
self.load_label(fixture_label)
File "D:\Projects\Navid Motor\Website\Django\NavidMotor.com\.venv\lib\site-packages\django\core\management\commands\loaddata.py", line 251, in load_label
for obj in objects:
File "D:\Projects\Navid Motor\Website\Django\NavidMotor.com\.venv\lib\site-packages\django\core\serializers\json.py", line 74, in Deserializer
raise DeserializationError() from exc
django.core.serializers.base.DeserializationError: Problem installing fixture 'D:\Projects\Navid Motor\Website\Django\NavidMotor.com\provinces.json'::
and by the looks of it, this time the problem is json.decoder.JSONDecodeError: Unexpected UTF-8 BOM (decode using utf-8-sig): line 1 column 1 (char 0), which I have no idea how to resolve and didn't find any instruction on how to solve this issue.
I did study the following questions, but all were for problems relating json library inside .py files, and since my problem occurs in command line using manage.py commands, I couldn't apply those solutions for my problem.
Possible simillar questions, but could not use the answers given:
First
Second
Third
Try to paste json into new file in vscode and save it.
Errorjson.decoder.JSONDecodeError: Unexpected UTF-8 BOM because your json files have UTF8-BOM encoding:
https://www.coderedcorp.com/blog/how-to-dump-your-django-database-and-load-it-into-/

Cannot override custom field __init__ and make migrations, throws error

I was attempting to create a custom model field and use it in a model as the docs demonstrate for BetterCharField shown here (you might have to scroll a bit down): https://docs.djangoproject.com/en/3.0/howto/custom-model-fields/#custom-database-types
My code in my models.py is as follows, almost verbatim from the docs example:
from django.db import models
# Create your models here.
class BetterCharField(models.Field):
def __init__(self, max_length, *args, **kwargs):
self.max_length = max_length
super().__init__(*args, **kwargs)
def db_type(self, connection):
return "char({})".format(self.max_length)
class MyModel(models.Model):
my_field = BetterCharField(25)
However, when trying to run python manage.py makemigrations with this models.py file, I get the following error every time:
Traceback (most recent call last):
File "/Users/dark_knight/test/venv/lib/python3.7/site-packages/django/db/migrations/state.py", line 413, in from_model
fields.append((name, field.clone()))
File "/Users/dark_knight/test/venv/lib/python3.7/site-packages/django/db/models/fields/__init__.py", line 512, in clone
return self.__class__(*args, **kwargs)
TypeError: __init__() missing 1 required positional argument: 'max_length'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "manage.py", line 21, in <module>
main()
File "manage.py", line 17, in main
execute_from_command_line(sys.argv)
File "/Users/dark_knight/test/venv/lib/python3.7/site-packages/django/core/management/__init__.py", line 401, in execute_from_command_line
utility.execute()
File "/Users/dark_knight/test/venv/lib/python3.7/site-packages/django/core/management/__init__.py", line 395, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/Users/dark_knight/test/venv/lib/python3.7/site-packages/django/core/management/base.py", line 328, in run_from_argv
self.execute(*args, **cmd_options)
File "/Users/dark_knight/test/venv/lib/python3.7/site-packages/django/core/management/base.py", line 369, in execute
output = self.handle(*args, **options)
File "/Users/dark_knight/test/venv/lib/python3.7/site-packages/django/core/management/base.py", line 83, in wrapped
res = handle_func(*args, **kwargs)
File "/Users/dark_knight/test/venv/lib/python3.7/site-packages/django/core/management/commands/makemigrations.py", line 142, in handle
ProjectState.from_apps(apps),
File "/Users/dark_knight/test/venv/lib/python3.7/site-packages/django/db/migrations/state.py", line 221, in from_apps
model_state = ModelState.from_model(model)
File "/Users/dark_knight/test/venv/lib/python3.7/site-packages/django/db/migrations/state.py", line 418, in from_model
e,
TypeError: Couldn't reconstruct field my_field on polls.MyModel: __init__() missing 1 required positional argument: 'max_length'
Why is this failing? I had yet to create any migrations at all for this project, let alone the field and model given here. I have my positional argument as 25 given to BetterCharField when I initialize it in my models.py file. What am I missing? I had a much more complex use case, but I built this example in a brand new test django project/app straight from the documentation, and it still fails.
This is documented behaviour:
You can’t modify the number of positional arguments in an already migrated custom field without raising a TypeError. The old migration will call the modified __init__ method with the old signature. So if you need a new argument, please create a keyword argument and add something like assert 'argument_name' in kwargs in the constructor.

django :UnicodeDecodeError: '

I want build a blog with Python 2.7 and Django 1.7.8.
When I use Django,I keep getting an error: UnicodeDecodeError.
The relevant code is:
#coding: utf-8
from django.db import models
class Entry(models.Model):
title = models.CharField(max_length=200)
body = models.TextField()
publish = models.BooleanField(default=False)
And ./manage.py makemigrations get an error:
Migrations for 'blog':
0001_initial.py:
- Create model Entry
Traceback (most recent call last):
File "manage.py", line 10, in <module>
execute_from_command_line(sys.argv)
File "/usr/local/lib/python2.7/dist-packages/Django-1.7.8-py2.7.egg/django/core/management/__init__.py", line 385, in execute_from_command_line
utility.execute()
File "/usr/local/lib/python2.7/dist-packages/Django-1.7.8-py2.7.egg/django/core/management/__init__.py", line 377, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/usr/local/lib/python2.7/dist-packages/Django-1.7.8-py2.7.egg/django/core/management/base.py", line 288, in run_from_argv
self.execute(*args, **options.__dict__)
File "/usr/local/lib/python2.7/dist-packages/Django-1.7.8-py2.7.egg/django/core/management/base.py", line 338, in execute
output = self.handle(*args, **options)
File "/usr/local/lib/python2.7/dist-packages/Django-1.7.8-py2.7.egg/django/core/management/commands/makemigrations.py", line 124, in handle
self.write_migration_files(changes)
File "/usr/local/lib/python2.7/dist-packages/Django-1.7.8-py2.7.egg/django/core/management/commands/makemigrations.py", line 143, in write_migration_files
migrations_directory = os.path.dirname(writer.path)
File "/usr/local/lib/python2.7/dist-packages/Django-1.7.8-py2.7.egg/django/db/migrations/writer.py", line 222, in path
return os.path.join(basedir, self.filename)
File "/usr/lib/python2.7/posixpath.py", line 80, in join
path += '/' + b
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe6 in position 10: ordinal not in range(128)
I don't see what's going wrong, any idea? I already add coding:utf-8 in top of code
do you have data in the models already?
if so, i am guessing you have some bad characters in there.
do you have a unicode or str method defined on the models?
if so, i suggest using them in a try statement of sorts like this:
def __str__():
try:
return "%s" % self.title
except:
return "%s" % self.pk
when you see only the PK, you will know that your 'title' field has bad data.
extend this to include whichever fields you want to display, not just title.
it looks like it fails when joining the path?
maybe you have folder names that can't be converted to ascii?
also , consider editing the file that is having the error? maybe add a print statement just before the line that fails that shows what is trying to be joined?
edit the file mentioned below, add the print statement to see what is trying to be joined?
File "/usr/lib/python2.7/posixpath.py", line 80, in join
path += '/' + b

Django South migration is throwing an error 'module' object has no attribute 'SET_NULL'

I just generated the migration scripts through ./manage.py schemamigration --auto and ran it. I get the following error. I am stumped as to what it could mean. I have been using SET_NULL for a while now. So this is something new that didn't occur earlier. Any idea what could be wrong?
Traceback (most recent call last):
File "./manage.py", line 16, in
execute_from_command_line(sys.argv)
File "/home/vivekv/.environments/fantain/local/lib/python2.7/site-packages/django/core/management/init.py", line 399, in execute_from_command_line
utility.execute()
File "/home/vivekv/.environments/fantain/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 "/home/vivekv/.environments/fantain/local/lib/python2.7/site-packages/django/core/management/base.py", line 242, in run_from_argv
self.execute(*args, **options.dict)
File "/home/vivekv/.environments/fantain/local/lib/python2.7/site-packages/django/core/management/base.py", line 285, in execute
output = self.handle(*args, **options)
File "/home/vivekv/.environments/fantain/local/lib/python2.7/site-packages/south/management/commands/schemamigration.py", line 111, in handle
old_orm = last_migration.orm(),
File "/home/vivekv/.environments/fantain/local/lib/python2.7/site-packages/south/utils/init.py", line 62, in method
value = function(self)
File "/home/vivekv/.environments/fantain/local/lib/python2.7/site-packages/south/migration/base.py", line 432, in orm
return FakeORM(self.migration_class(), self.app_label())
File "/home/vivekv/.environments/fantain/local/lib/python2.7/site-packages/south/orm.py", line 48, in FakeORM
_orm_cache[args] = _FakeORM(*args)
File "/home/vivekv/.environments/fantain/local/lib/python2.7/site-packages/south/orm.py", line 134, in init
self.retry_failed_fields()
File "/home/vivekv/.environments/fantain/local/lib/python2.7/site-packages/south/orm.py", line 377, in retry_failed_fields
fname, modelname, e
ValueError: Cannot successfully create field 'winner' for model 'match': 'module' object has no attribute 'SET_NULL'.
OK This is not a valid question. I am embarrassed to admit I made a small tweak on the migration script that caused the problem. Please ignore this question - seems like I dont have a way to delete a question I had asked!
I wrote the solution here
Short answer: use models.SET_NULL instead of "SET_NULL".
You need to replace this in all migrations which have b"SET_NULL"

changing django default model settings

I'm just starting with the django creating your own app tutorial (creating a Poll) I'm deviating slightly as I'm wanting to create an app using my own database model that already exists.
And in the tutorial it says
Table names are automatically
generated by combining the name of
the app (polls) and the lowercase
name of the model -- poll and choice.
(You can override this behavior.)
Primary keys (IDs) are added
automatically. (You can override
this, too.)
By convention, Django appends
"_id" to the foreign key field
name. Yes, you can override this,
as well.
But I can't see where it mentions how you can override this behaviour? I've defined my model as so
from django.db import models
# Create your models here.
class Channels(models.Model):
channelid = models.IntegerField()
channelid.primary_key = True
channelname = models.CharField(max_length=50)
Now when I go in to the shell this is what I get
>>> from tvlistings.models import *
>>> Channels.objects.all()
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "C:\Python26\lib\site-packages\django\db\models\query.py", line 67, in __
repr__
data = list(self[:REPR_OUTPUT_SIZE + 1])
File "C:\Python26\lib\site-packages\django\db\models\query.py", line 82, in __
len__
self._result_cache.extend(list(self._iter))
File "C:\Python26\lib\site-packages\django\db\models\query.py", line 271, in i
terator
for row in compiler.results_iter():
File "C:\Python26\lib\site-packages\django\db\models\sql\compiler.py", line 67
7, in results_iter
for rows in self.execute_sql(MULTI):
File "C:\Python26\lib\site-packages\django\db\models\sql\compiler.py", line 73
2, in execute_sql
cursor.execute(sql, params)
File "C:\Python26\lib\site-packages\django\db\backends\util.py", line 15, in e
xecute
return self.cursor.execute(sql, params)
File "C:\Python26\lib\site-packages\django\db\backends\mysql\base.py", line 86
, in execute
return self.cursor.execute(query, args)
File "C:\Python26\lib\site-packages\MySQLdb\cursors.py", line 166, in execute
self.errorhandler(self, exc, value)
File "C:\Python26\lib\site-packages\MySQLdb\connections.py", line 35, in defau
lterrorhandler
raise errorclass, errorvalue
DatabaseError: (1146, "Table 'tvlistings.tvlistings_channels' doesn't exist")
Obviously it can't find the table tvlistings_channels as it's actually called channels. So how do I change the default?
You can override Model behavior in Django largely through the use of an inner Meta class
db_table allows you to rename the table name
specifying another field as the primary key will have it use that rather than a surrogate key (not in the Meta class, just in the model itself)
You should try and work your way all through the tutorial before you try and customise things. All these things are covered in the actual documentation, but it's best to have a basic understanding of things first before diving into that.
FWIW, here are the docs on defining your own primary key and specifying a table name. But really, do the tutorial as written first.

Categories

Resources