I would like to use the modeltranslation package in a Django application that uses the flatpages app.
I installed both, followed the model translation docs, and created a translation.py file, which I put in the main app (where all the global stuff lies), as I can't put it directly in the flat pages app (Django code is a requirement and is not committed to VCS).
# django/main/translation.py
from modeltranslation.translator import translator, TranslationOptions
from django.contrib.flatpages.models import FlatPage
class FlatPageTranslationOptions(TranslationOptions):
fields = ('title', 'content')
translator.register(FlatPage, FlatPageTranslationOptions)
Then I ran python manage.py makemigrations, and it created a migration file in the flatpages app /usr/local/lib/python3.8/site-packages/django/contrib/flatpages/migrations/0002_auto_20211118_1558.py. It would be again in the Django code, so I tried to simply move it to the main app at django/main/migrations/0002_flatpages_translations.py (there is already an unrelated 0001_initial.py migration, which has no dependencies):
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('flatpages', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='flatpage',
name='content_en',
field=models.TextField(blank=True, null=True, verbose_name='content'),
),
migrations.AddField(
model_name='flatpage',
name='content_fr',
field=models.TextField(blank=True, null=True, verbose_name='content'),
),
migrations.AddField(
model_name='flatpage',
name='title_en',
field=models.CharField(max_length=200, null=True, verbose_name='title'),
),
migrations.AddField(
model_name='flatpage',
name='title_fr',
field=models.CharField(max_length=200, null=True, verbose_name='title'),
),
]
And... when I finally try to run the migration (python manage.py migrate), I got this error:
CommandError: Conflicting migrations detected; multiple leaf nodes in the migration graph: (0001_initial, 0002_flatpages_translations in main).
To fix them run 'python manage.py makemigrations --merge'
I tried the --merge flag, but got another error: ValueError: Could not find common ancestor of ['0001_initial', '0002_flatpages_translations']
Is it possible to achieve what I want to do?
Found a solution, so I post it here if someone has the same problem. According Django documentation, you can specify the package where migration modules can be found on a per-app basis.
So, in settings.py, add:
MIGRATION_MODULES = {
'flatpages': 'main.migrations.flatpages',
}
Then move the migration file 0002_flatpages_translations.py in django/main/migrations/flatpages/. In the case of the flatpages app, you will also need to copy the 0001_initial.py migration file from the flatpage app, inside this directory.
And you're good, Django now searches the migrations for the flatpages app in your new directory.
Related
I am defining a Model containing a FileField and cannot save the Files this FileField should contain in the media folder for unrelated reasons. Therefore I need to define a FileStorage that saves into a different Path.
When defining said FileStorage in my model and passing it the DJANGO_ROOT variable from my django settings to build my location path, this gets resolved into a system specific path once I generate migrations for my models.
Because the path is now specific to my development directories, I cannot apply the generated migration file on all of the production servers and generating migrations on all of the production servers is obviously not an option.
I have also tried editing the path inside the auto generated migration itself, making it dependent on the django settings in there. Sadly, the manage.py migrate command tells me that it wants to generate new migrations for that model.
How can I pass a relative path to my FileStorage location, allowing me to generate migrations for my production servers?
My model:
class ModelWithFile(models.Model):
file = models.FileField(
storage=FileSystemStorage(location=os.path.join(settings.DJANGO_ROOT, "folder_name"),
verbose_name=_("FileObject"),
)
Auto generated migration:
from django.db import migrations, models
from django.conf import settings
import django.core.files.storage
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='ModelWithFile',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('file', models.FileField(upload_to=b'', storage=django.core.files.storage.FileSystemStorage(base_url=None, location='/home/myusername/repros/thisrepro/folder_name/'), verbose_name='File')),
],
options={
'verbose_name': 'Model With File',
},
),
]
What I tried
Pass os.path.join(settings.DJANGO_ROOT, "folder_thats_not_media") as my location.
What I was expecting
for the autogenerated migration to use the same relative path as defined in the settings
What did I experience?
The location path in my auto generated migration was resolved to a system specific path
Finished creating the models file, typed python manage.py makemigrations main and I get a reply back, 'no installed app with label 'main'. when I do python manage.py migrate, it says Apply all migrations: admin, auth, contenttypes, sessions. I even spent considerable time double checking my spelling and it is correct. Any ideas on how I can fix it?
your app.py must look like this:
from django.apps import AppConfig
class MainConfig(AppConfig):
name = 'main'
verbose_name = 'Some Name'
You need to add your app main to the INSTALLED_APPS setting [Django-doc] in the settings.py:
# settings.py
INSTALLED_APPS = [
# …,
'main'
]
How do you disable migrations for specific apps in Django>=1.7?
I'm trying to upgrade from Django 1.6 to 1.7, and I made some trivial changes to Django's auth app to change labels, but a design flaw in Django>=1.7 now treats all attributes as part of the database schema, triggering a new migration. Moreover, running manage.py makemigration myapp generates a migration for all other apps touching myapp, so even though I'm not explicitly trying to create a migration for auth, it's forcing me to do so, and I see no way to turn this off.
This is creating havoc, since I have a dozen apps that touch auth, so this is causing Django to create over a dozen pointless migrations.
I tried creating a custom auth migration directory using MIGRATION_MODULES, but doesn't seem to work. Any app that relies on auth now throws an error like:
ValueError: Lookup failed for model referenced by field helpdesk.Queue.group: auth.Group
If I try to migrate auth. How do I fix this? Ideally, the simplest solution would be to just "turn off" migrations for auth, since I'm not actually making any changes to it.
Edit: This is the custom migration Django forces me to generate:
class Migration(migrations.Migration):
dependencies = [
('admin', '0001_initial'),
('auth', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='LogEntry',
fields=[
],
options={
'ordering': ('-action_time',),
'verbose_name': 'log entry',
'proxy': True,
'verbose_name_plural': 'log entries',
},
bases=('admin.logentry',),
),
migrations.AlterField(
model_name='permission',
name='name',
field=models.CharField(max_length=500, verbose_name='name'),
preserve_default=True,
),
migrations.AlterField(
model_name='user',
name='username',
field=models.CharField(help_text='Required. 30 characters or fewer. Letters, digits and #/./+/-/_ only.', unique=True, max_length=75, verbose_name='username', validators=[django.core.validators.RegexValidator('^[\\w.#+-]+$', 'Enter a valid username.', 'invalid')]),
preserve_default=True,
),
]
My custom changes are to make the username and email fields the same length (because the two are the same in my system), as well as change the default validator to validate them both as an email address. I've been using these changes since Django 1.3. Presumably, they're only a problem now that I'm no longer using South and have to re-generate all my migrations.
And it looks like I can't use MIGRATION_MODULES to even generate this into a custom migration folder, because I have some other apps that depend on auth's 0001_initial migration, like:
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
So if I override it with MIGRATION_MODULES like:
MIGRATION_MODULES = {
'auth': 'myoverrides.auth_migrations',
}
that migration effectively disappears, throwing the error.
It's a bit of a hack, but I modified my settings.py to check sys.argv for "makemigrations" and remove the conflicting apps, that are effectively unmanaged, from my INSTALLED_APPS list. This allowed me to properly generate a custom auth migration. e.g.
if 'makemigrations' in sys.argv
INSTALLED_APPS.remove('conflicting_third_party_app')
the django doc says to change the sites name and domain in the django.contrib.sites framework one should use a migration [1].
But they forgot to mention where I should put this migration. I tried to create a directory named "sites" and a directory named "django.contrib.sites". But no matter in which directory I put my migration, manage.py migration always says there is nothing to update.
I also tried to run python manage.py makemigrations --empty sites, but then the migration is created in the lib directory: ve/lib/python3.5/site-packages/django/contrib/sites/migrations/0003_auto_20160904_2144.py. This may be correct behaviour, but then I cannot set my change under source control.
In case something is wrong with my migration, here it is:
from __future__ import unicode_literals
from django.db import migrations, models
def set_site_name(apps, schema_editor):
Sites = apps.get_model('django.contrib.sites', 'site')
site = Sites.objects.filter(id=1).first()
if site != None:
site.name = "name"
site.domain = "name.com"
class Migration(migrations.Migration):
initial = True
operations = [
migrations.RunPython(set_site_name),
]
So my question is: where does django expect to find those migrations?
Thank you very much in advance for your help.
[1] https://docs.djangoproject.com/en/1.10/ref/contrib/sites/#enabling-the-sites-framework
Each app in a Django project must have a unique label. Naming your app sites isn't a good idea - it will clash with the django.contrib.sites app unless you change the label in the app config class.
If you have an existing app specific to your project, you could use that app to store the data migration.
Alternatively choose a different name like mysites. Create the app with ./manage.py startapp mysite, add the app to your INSTALLED_APPS, then create a blank migration.
I am trying to create a 'Reusable App'. I've written some database models, and then copy/pasted the folder (which is supposed to be my reusable app) into the Project I want to be using it in. I then added the folder's name to INSTALLED_APPS in my settings.
Then I used South to run:
python manage.py schemamigration test --initial --settings=settings_local
and:
python manage.py migrate test --settings=settings_local
When I tried accessing this app's models in the admin I got a relation does not exist. I went in my PostgreSQL and realized the tables were not created with those South commands.
Any idea what I am doing wrong?
UPDATE:
I am using Django 1.5.10 and South 0.7.5
The migration that is created when running schemma migration
class Migration(SchemaMigration):
def forwards(self, orm):
# Adding model 'Category'
db.create_table(u'test_category', (
(u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('name', self.gf('django.db.models.fields.CharField')(unique=True, max_length=200)),
))
db.send_create_signal(u'test', ['Category'])
def backwards(self, orm):
# Deleting model 'Category'
db.delete_table(u'test_category')
models = {
u'test.category': {
'Meta': {'object_name': 'Category'},
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '200'})
}
}
complete_apps = ['test']
I've generated the migrations and installed the app in a project of mine without a problem with a MySQL Db.
I've not really changed anything, but I did fix an import error in your form.
Your form inherits BaseInlineFormSet which you tried to import from django.forms but it should be imported from;
from django.forms.models import BaseInlineFormSet
I've zipped up the app as it is running in my project;
https://www.dropbox.com/s/tqyi9su942rsp1u/ubiwhere_games.zip?dl=0