For example:
{{{
class Journal(Model):
issn = models.CharField(max_length=9, primary_key=True)
name = models.CharField(max_length=255)
class Biblio(Model):
# There already exists a field called issn in the Biblio model
# issn = models.CharField(max_length=50, default="", blank=True)
journal = models.ForeignKey(
Journal,
related_name="+",
db_column="issn",
db_constraint=False,
db_index=False,
on_delete=models.DO_NOTHING,
default="",
blank=True,
max_length=50,
)
}}}
In this example, we define a journal field from issn field and we want to
do a fake migration.
But the migratation will generate DDL like this:
{{{
--
-- Remove field issn from biblio
--
ALTER TABLE `userlibrary_biblio` DROP COLUMN `issn`;
--
-- Add field issn_record to biblio
--
ALTER TABLE `userlibrary_biblio` ADD COLUMN `issn` varchar(9) DEFAULT ''
NOT NULL;
ALTER TABLE `userlibrary_biblio` ALTER COLUMN `issn` DROP DEFAULT;
}}}
which is kind of awkward because that means Django will force max_length=9
and this is not we want.
--
Ticket URL: <https://code.djangoproject.com/ticket/35129>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
* status: new => closed
* resolution: => invalid
Comment:
`db_constraint` is only to disable creation of foreign key constraints in
the tables and to allow for handling legacy database structures (if you
don't other choice). It has nothing to do with a column data type that
should always match a data type of the referenced column. Moreover,
`max_length` is not a proper keyword argument for `ForeignKey` and as such
is ignored.
--
Ticket URL: <https://code.djangoproject.com/ticket/35129#comment:1>
Comment (by elonzh):
Replying to [comment:1 Mariusz Felisiak]:
> `db_constraint` is only to disable creation of foreign key constraints
in the tables and to allow for handling legacy database structures (if you
don't other choice). It has nothing to do with a column data type that
should always match a data type of the referenced column. Moreover,
`max_length` is not a proper keyword argument for `ForeignKey` and as such
is ignored.
I know those parameters are intentionally ignored, what I want is joining
tables without db_constraint. Django doesn't provide a method to achieve
this, so I define a fake ForeignKey as a workround.
I am curious that since it is allowed to set db_constraint=True for
handling legacy database structures, why `max_length` should be always
match a data type of the referenced column.
This behavior will make unnessary migrations for legacy database
structures, right?
--
Ticket URL: <https://code.djangoproject.com/ticket/35129#comment:2>
Comment (by Natalia Bidart):
Replying to [comment:2 elonzh]:
> [...] I want is joining tables without db_constraint. Django doesn't
provide a method to achieve this, so I define a fake ForeignKey as a
workround.
Another way of achieving this is by using a slightly more manual approach
involving subqueries. You could also consider seeking more help or ideas
in how to resolve this without using a foreign key by posting your
question n the [https://forum.djangoproject.com/c/users/using-the-orm/17
Django Forum], or using any of the user support channels from
[https://docs.djangoproject.com/en/dev/faq/help/#how-do-i-do-x-why-
doesn-t-y-work-where-can-i-go-to-get-help this link].
--
Ticket URL: <https://code.djangoproject.com/ticket/35129#comment:3>
Comment (by Simon Charette):
I think this will eventually come in a form or the other eventually
through a `Relation` object
[http://charettes.name/djangoconus2022/slides.html#39 that can be defined
at the model level] but in the mean time your best bet is to use (at your
own risks) the undocumented `django.db.models.ForeignObject` object to
define such relationships.
{{{#!python
class Journal(Model):
issn = models.CharField(max_length=9, primary_key=True)
name = models.CharField(max_length=255)
class Biblio(Model):
issn = models.CharField(max_length=50, default="", blank=True)
journal = models.ForeignObject(
Journal,
models.DO_NOTHING,
from_fields=["issn"],
to_fields=["issn"],
)
}}}
Under the hood `ForeignKey` is `Field` + `ForeignObject` + the equivalent
of a `ForeignKeyConstraint(ForeignObject)` entry in
`Model._meta.constraints` so if you care about the ORM + JOIN generation
part and don't want a database constraint it's likely what you're looking
for.
--
Ticket URL: <https://code.djangoproject.com/ticket/35129#comment:4>
Comment (by elonzh):
Replying to [comment:4 Simon Charette]:
Thanks for your suggestion, it's very helpful.
--
Ticket URL: <https://code.djangoproject.com/ticket/35129#comment:5>