Django-parler unique_together constraint between translated and normal field

297 views Asked by At

I want to make unique_together constraint with django-parler between translated field and normal field.

I'd like to do this:

class Part(TranslatableModel):
    code = CharField('code')
    translations = TranslatedFields(
        name = CharField('name')
    )

    class Meta:
        constraints = [
            UniqueConstraint(
                fields=['code', 'name'],
                name='constraint_name',  
            )
        ]

but then I get error:

Traceback (most recent call last):
  File "manage.py", line 14, in <module>
    execute_from_command_line(sys.argv)
  File "/home/lauri/työt/p/venv/lib/python3.6/site-packages/django/core/management/__init__.py", line 381, in execute_from_command_line
    utility.execute()
  File "/home/lauri/työt/p/venv/lib/python3.6/site-packages/django/core/management/__init__.py", line 375, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/home/lauri/työt/p/venv/lib/python3.6/site-packages/django/core/management/base.py", line 323, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/home/lauri/työt/p/venv/lib/python3.6/site-packages/django/core/management/base.py", line 364, in execute
    output = self.handle(*args, **options)
  File "/home/lauri/työt/p/venv/lib/python3.6/site-packages/django/core/management/base.py", line 83, in wrapped
    res = handle_func(*args, **kwargs)
  File "/home/lauri/työt/p/venv/lib/python3.6/site-packages/django/core/management/commands/migrate.py", line 234, in handle
    fake_initial=fake_initial,
  File "/home/lauri/työt/p/venv/lib/python3.6/site-packages/django/db/migrations/executor.py", line 117, in migrate
    state = self._migrate_all_forwards(state, plan, full_plan, fake=fake, fake_initial=fake_initial)
  File "/home/lauri/työt/p/venv/lib/python3.6/site-packages/django/db/migrations/executor.py", line 147, in _migrate_all_forwards
    state = self.apply_migration(state, migration, fake=fake, fake_initial=fake_initial)
  File "/home/lauri/työt/p/venv/lib/python3.6/site-packages/django/db/migrations/executor.py", line 245, in apply_migration
    state = migration.apply(state, schema_editor)
  File "/home/lauri/työt/p/venv/lib/python3.6/site-packages/django/db/migrations/migration.py", line 124, in apply
    operation.database_forwards(self.app_label, schema_editor, old_state, project_state)
  File "/home/lauri/työt/p/venv/lib/python3.6/site-packages/django/db/migrations/operations/models.py", line 827, in database_forwards
    schema_editor.add_constraint(model, self.constraint)
  File "/home/lauri/työt/p/venv/lib/python3.6/site-packages/django/db/backends/sqlite3/schema.py", line 405, in add_constraint
    self._remake_table(model)
  File "/home/lauri/työt/p/venv/lib/python3.6/site-packages/django/db/backends/sqlite3/schema.py", line 279, in _remake_table
    self.create_model(new_model)
  File "/home/lauri/työt/p/venv/lib/python3.6/site-packages/django/db/backends/base/schema.py", line 296, in create_model
    constraints = [constraint.constraint_sql(model, self) for constraint in model._meta.constraints]
  File "/home/lauri/työt/p/venv/lib/python3.6/site-packages/django/db/backends/base/schema.py", line 296, in <listcomp>
    constraints = [constraint.constraint_sql(model, self) for constraint in model._meta.constraints]
  File "/home/lauri/työt/p/venv/lib/python3.6/site-packages/django/db/models/constraints.py", line 89, in constraint_sql
    fields = [model._meta.get_field(field_name).column for field_name in self.fields]
  File "/home/lauri/työt/p/venv/lib/python3.6/site-packages/django/db/models/constraints.py", line 89, in <listcomp>
    fields = [model._meta.get_field(field_name).column for field_name in self.fields]
  File "/home/lauri/työt/p/venv/lib/python3.6/site-packages/django/db/models/options.py", line 567, in get_field
    raise FieldDoesNotExist("%s has no field named '%s'" % (self.object_name, field_name))
django.core.exceptions.FieldDoesNotExist: NewPart has no field named 'name'

I'm not very aware of insides of django-parler so I'm not able to move forward with this.

1

There are 1 answers

0
Mamatkasym Mamarasul On

When you make migrations there will be two tables Part and PartTranslation. What you want is single translation for single post. So the following lines solves your problem

    translations = TranslatedFields(
        name = CharField('name'),
        meta={'unique_together': [('name', 'language_code')]}
    )

For uniqueness of Parts just make the code field unique.

  code = CharField('code', unique=True)