When using dumpdata, Django recommends using natural_key() to serialize objects that refer to Permission or ContentType:
--natural-foreign
Uses the natural_key() model method to serialize any foreign key and
many-to-many relationship to objects of the type that defines the
method. If you’re dumping contrib.auth Permission objects or
contrib.contenttypes ContentType objects, you should probably use this
flag. See the natural keys documentation for more details on this and
the next option.
This means that rather than dumping foreignkey contentype with pk=1, it is dumped as:
"content_type": [
"myapp",
"mymodel"
],
Why would you not always use --natural-key?
What use cases are there where --natural-key would be inappropriate?
Related
I want to rename a model in Django 3.2, keep my existing migrations and be able to both migrate a db with the old table name and create a db from scratch.
I've started by renaming the model class and all references to it in the code. As "./manage.py makemigrations" did not automatically create a migration, I manually created a migration that renames the model:
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('market_integrations', '0003_migration'),
]
operations = [
migrations.RenameModel('OldModelName', 'NewModelname')
]
My initial idea is that I should not update existing migrations, as I never do when creating other migrations. However, the references to the old model in the old migrations cause a LookupError when I run "./manage.py migrate". I've tried using both the model name string and apps.get_model(). Migration code samples that break:
operations = [
migrations.CreateModel(
name="OldModelName",
...
)
]
operations = [
migrations.CreateModel(
name=apps.get_model("myapp", "OldModelName"),
...
)
]
As keeping the old model name in old migrations didn't work, I replaced the old model name in old migrations with the new name. After doing that, "./manage.py migrate" ran successfully, including the model renaming migration. However, when I try to create a new database, the model renaming migration fails because that new database never had a table with the old name.
What should I do to be able to preserve my migrations and have them working in both existing and new databases?
I have already checked Django migration strategy for renaming a model and relationship fields , but I didn't find the answer to my question there.
Please attach the full model (you can delete irrelevant fields) and the migration you created in your initial question (I cannot comment on your initial post yet, so I have to mention it in an answer).
This is important because I think there are foreign keys pointing to the model you want to rename.
Or are you trying to rename Foo to Bar and create a new Foo?
Does the error also occur if you try to start the server after your initial idea?
Your initial idea of keeping existing migrations untouched seems good, because you will be able to run it on all your environments (local, dev, prod, etc), and approach 2 would require manual renaming of database tables and fields.
I might be able to extend my answer after you provide models and migrations.
migrations.RenameModel(
old_name="ModelA",
new_name="ModelB",
),
migrations.AlterField(
model_name="myrelatedmodel",
name="somefieldname",
field=models.ForeignKey(
# change the properties accordingly (best copy it over). The database may only change to="table"
null=True,
on_delete=django.db.models.deletion.SET_NULL,
to="myapp.modelb",
),
),
If this did not work, where does the error come from? You can try to isolate your migrations and models from the rest of the code (like in a new empty project attached to the same database). Maybe this will help you find out if the error is from a leftover reference to OldModelName or some weird error. Just as an idea so you don't spend time looking at the wrong place
Try to do one change and one migration at a time. You can later squash them. If django does not auto-detect the renaming of your model, it means that all fields related to this model will fail too.
Revert everything to the working state before renaming
Make sure all migrations are applied
Rename the model and create a migration to only rename the model. Are you able to apply it?
if not, try to manually modify all related fields (one2one, foreignkey, etc)
If that still fails, create a copy of your model in models.py, rename the copied model and try to use migrations.RunPython() in a new migration file to copy all the data from the old table to the new one.
If you only have one populated database, you might get away with replacing all ModelA occurrences with ModelB and change the structure of your database.
Best of luck!
// don't delete database entries but set the newly added attribute deletedAt
// to the current date (when deletion was done). paranoid will only work if
// timestamps are enabled
paranoid: true,
I used Sequelize.js ORM, and there was option paranoid like above description. (from Sequelize.js tutorial docs)
I want to make my Django Model paranoid.
I googled with keywords like "django paranoid", but i couldn't find informations. What is a general name for the option "paranoid" and how can i make my django model act like the option?
Or should I make mixins or middlewares to make paranoid?
of course, you can use django-paranoid
this library will add deleted_at, updated_at and created_at field, also a soft delete method.
You only need extend to model with ParanoidModel.
For see the deleted object you can use objects_with_deleted:
MyModel.objects_with_deleted.last()
and if do you want do hard delete an object you only should use True param:
m = MyModel.objects.last()
m.delete(True)
I'm trying to load a fixture and it gives me:
django.db.utils.OperationalError: Problem installing fixtures: no such column: REFERRED.number
Unfortunately, I cannot show the json, because there is all kind of private stuff in there, but I was hoping someone might explain to me what the REFERRED might mean. What kind of error am I looking for?
I made a few migrations and now the DB is out of wack. So the json is slightly off to the DB. There are multiple things called number though. Referred sounds it's some kind of foreignkey error!? Can you give me any hint what to look for?
I had a similar issue and found out what REFERRED was by adding print(query) in django/db/backends/sqlite3/base.py#L297. That showed me all the queries django was running against my sqlite3 database.
In my case, loaddata was not finding the field id (the primary key field that is default in django) for a model in which I had set primary_key=True to one of its fields. Eventhough django was not automatically generating the id field (correct behaviour), loaddata kept looking for the id field. A possible solution would be to add --natural-primary option, but that didn't work for me ATM.
Ref: https://docs.djangoproject.com/en/1.11/topics/serialization/#topics-serialization-natural-keys
I've written my owner adapter and serializer for my Ember.js application. I follow the JSON API standard (the ID format), so most of my JSON looks something like this:
{
"id": "2364",
"name": "Test",
"links": {
"single": "2834",
"multiple": ["2292", "9584", "8475"]
}
}
However, all of my relationships are loaded lazily (I defined the async attribute as true). This is required, because some of the records can become quite large. The problem is when I try to serialize the model. If the relationship isn't loaded yet, I won't get the ID for the related model. So let's say I edit the name of the model above and try to save it. I'll get this JSON:
{
"id": "2364",
"name": "This has been edited",
"links": {
"single": null,
"multiple": []
}
}
Because the relationships aren't loaded yet, it gives me empty values. However, because the relationships haven't been edited, they should be exactly the same as when they came in. To get that data back, I can use model.get('data') and get an object that contains the IDs that were originally returned from the server. So if I know a relationship is unloaded, I can call model.get('data.relationshipName') and get those original IDs back.
Now the real problem: if the relationship is loaded fully, I want to serialize it as it exists, in case it was edited. However, if it is not loaded fully, I don't want to attempt to load it. In that case, I can just get the IDs from the data property. So, how can I determine if a relationship is loaded or not, without loading it?
As usual, I did quite a bit of legwork and trickery, but I figured it out. Here's what you do:
Have all of your models inherit from a single base class. In that base class, you want to do three things. First, in the init method, created a hash (object) on the instance (leave it empty). Next, override the get method, and if the user tries to access one of the relationships, update the hash you created to reflect that. Finally add a method like wasRelationshipAccessed(name) to the class to read from the hash. This will tell you exactly which relationships where accessed, and by process of elimination, which ones weren't.
Also in that base class, have the init method create another hash. This one is going to store the original values of the relationships from the server. I called mine originalLinks.
Override DS.Store and assign it to App.Store. In that class, override the push method. In the override, call this._super.apply(this, arguments) and save the return value. That return value is the record. Now that you have both the data from the server and the record, insert the relationships from the server into the originalLinks hash you made above.
Finally, in your serializer, use your wasRelationshipAccessed function. If the relationship was accessed, it was loaded. If it wasn't accessed, get the data from the originalLinks hash.
And that's all there is to it. If you're going to do this, I highly suggest writing unit tests for your serializer, adapter and that part of the store. That will ensure that you'll catch any changes to the internals of Ember-Data.
I'm currently working on a REST api, using django. I started using the nice djangorestframework, which I loved to use the "View" class.
But, I'm facing with the serialization problem.
I do not like the Serialization using the Serializer classes.
The main goal is to prepare a sort of giant dict, with all the infos, and give it to a renderer class which translate it into an xml, json, yaml, depending on the "Accept:" HTTP header. The goal is classy, but 60% of the CPU time is spend on creating the "GIANT DICT".
This dict can be created using django Models, but I think using on the fly instanciated classes and object is VERY un-efficient ? I'm trying to use some QuerySet methods to filter which models member I want to have, and getting a simple dict : the ::values() method, but unfornately, I can't access the m2m and foreignkey from my models.
Did you already tried this ? Any though ?
You could use the QuerySet's iterator method:
... For a QuerySet which returns a large number of objects that you only
need to access once, this can results in better performance and a
significant reduction in memory.
Your code should looks like:
for obj in SomeModel.objects.values_list('id', 'name').iterator():
# do something