Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

443
Views
Error al usar CheckConstraint en Model.Meta junto con Django GenericForeignKey: las referencias de campos unidos no están permitidas en esta consulta

Estoy tratando de restringir GFK para que solo apunte a objetos de algunos modelos, y pensé que CheckConstraint sería una excelente manera de hacerlo, sin embargo, recibo este error

 class ManualAdjustment(Model): content_type = models.ForeignKey(ContentType, null=True, on_delete=models.CASCADE) object_id = models.PositiveIntegerField(null=True) booking_obj = GenericForeignKey('content_type', 'object_id') # should point to a app1.Booking1 or app2.Booking2 or app3.Booking3 only - trying to enforce this via CheckConstraint class Meta: constraints = [ models.CheckConstraint( check= Q(content_type__app_label='app1', content_type__model='booking1') | Q(content_type__app_label='app2', content_type__model='booking2') | Q(content_type__app_label='app3', content_type__model='booking3'), name='myconstraint_only_certain_models'), ]

Me sale error al migrar

 execute_from_command_line(sys.argv) File "/Users/myuser/.virtualenvs/xenia371/lib/python3.7/site-packages/django/core/management/__init__.py", line 381, in execute_from_command_line utility.execute() File "/Users/myuser/.virtualenvs/xenia371/lib/python3.7/site-packages/django/core/management/__init__.py", line 375, in execute self.fetch_command(subcommand).run_from_argv(self.argv) File "/Users/myuser/.virtualenvs/xenia371/lib/python3.7/site-packages/django/core/management/base.py", line 323, in run_from_argv self.execute(*args, **cmd_options) File "/Users/myuser/.virtualenvs/xenia371/lib/python3.7/site-packages/django/core/management/commands/sqlmigrate.py", line 30, in execute return super().execute(*args, **options) File "/Users/myuser/.virtualenvs/xenia371/lib/python3.7/site-packages/django/core/management/base.py", line 364, in execute output = self.handle(*args, **options) File "/Users/myuser/.virtualenvs/xenia371/lib/python3.7/site-packages/django/core/management/commands/sqlmigrate.py", line 64, in handle sql_statements = executor.collect_sql(plan) File "/Users/myuser/.virtualenvs/xenia371/lib/python3.7/site-packages/django/db/migrations/executor.py", line 225, in collect_sql state = migration.apply(state, schema_editor, collect_sql=True) File "/Users/myuser/.virtualenvs/xenia371/lib/python3.7/site-packages/django/db/migrations/migration.py", line 124, in apply operation.database_forwards(self.app_label, schema_editor, old_state, project_state) File "/Users/myuser/.virtualenvs/xenia371/lib/python3.7/site-packages/django/db/migrations/operations/models.py", line 827, in database_forwards schema_editor.add_constraint(model, self.constraint) File "/Users/myuser/.virtualenvs/xenia371/lib/python3.7/site-packages/django/db/backends/base/schema.py", line 343, in add_constraint sql = constraint.create_sql(model, self) File "/Users/myuser/.virtualenvs/xenia371/lib/python3.7/site-packages/django/db/models/constraints.py", line 47, in create_sql check = self._get_check_sql(model, schema_editor) File "/Users/myuser/.virtualenvs/xenia371/lib/python3.7/site-packages/django/db/models/constraints.py", line 37, in _get_check_sql where = query.build_where(self.check) File "/Users/myuser/.virtualenvs/xenia371/lib/python3.7/site-packages/django/db/models/sql/query.py", line 1296, in build_where return self._add_q(q_object, used_aliases=set(), allow_joins=False, simple_col=True)[0] File "/Users/myuser/.virtualenvs/xenia371/lib/python3.7/site-packages/django/db/models/sql/query.py", line 1312, in _add_q current_negated, allow_joins, split_subq, simple_col) File "/Users/myuser/.virtualenvs/xenia371/lib/python3.7/site-packages/django/db/models/sql/query.py", line 1318, in _add_q split_subq=split_subq, simple_col=simple_col, File "/Users/myuser/.virtualenvs/xenia371/lib/python3.7/site-packages/django/db/models/sql/query.py", line 1199, in build_filter raise FieldError("Joined field references are not permitted in this query") django.core.exceptions.FieldError: Joined field references are not permitted in this query

¿Alguna pista sobre cómo resolver esto? He usado GFK antes, pero con la nueva restricción de verificación, ahora puede ser una forma muy segura de errores, si pudiera hacer que esto migre

Gracias

over 4 years ago · Santiago Trujillo
1 answers
Answer question

0

No es posible lograr esto usando la funcionalidad CheckConstraint . Django traduce todos los comandos ORM a los comandos específicos de la base de datos de bajo nivel, y dicha creación de restricciones no es posible ni siquiera en el nivel de la base de datos. De hecho, podemos aplicar CheckConstraint a una sola fila que se agrega/actualiza solamente.

La nota en la documentación de PostgreSQL dice:

PostgreSQL no admite restricciones CHECK que hagan referencia a datos de tablas que no sean la fila nueva o actualizada que se está comprobando. Si bien una restricción CHECK que viola esta regla puede parecer que funciona en pruebas simples, no puede garantizar que la base de datos no alcance un estado en el que la condición de la restricción sea falsa (debido a cambios posteriores de las otras filas involucradas). Esto provocaría un error en el volcado y la recarga de la base de datos. La recarga podría fallar incluso cuando el estado completo de la base de datos es consistente con la restricción, debido a que las filas no se cargan en un orden que satisfaga la restricción. Si es posible, use restricciones UNIQUE, EXCLUDE o FOREIGN KEY para expresar restricciones entre filas y entre tablas.

Si lo que desea es una verificación única contra otras filas en la inserción de la fila, en lugar de una garantía de coherencia mantenida continuamente, se puede usar un disparador personalizado para implementar eso. (Este enfoque evita el problema de volcado/recarga porque pg_dump no reinstala los activadores hasta después de recargar los datos, por lo que la verificación no se aplicará durante un volcado/recarga).

Por lo tanto, la única forma de introducir las restricciones deseadas es mediante activadores de base de datos. Puede crear una migración vacía y agregarle un activador de base de datos.

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!