Vahid Jarazi
Tengo un modelo como este:
class Hop(models.Model):
migration = models.ForeignKey('Migration')
host = models.ForeignKey(User, related_name="host_set")
¿Cómo puedo hacer que la clave principal sea la combinación de migration
y host
?
Karthikr
Actualizar Django 4.0
La documentación de Django 4.0 recomienda usar Restricción única con la opción de restricciones en lugar de únicos_juntos.
Usar Restricción única con la opción de restricciones en su lugar.
Restricción única ofrece más funciones que únicos_juntos. únicos_juntos puede quedar obsoleto en el futuro.
class Hop(models.Model):
migration = models.ForeignKey('Migration')
host = models.ForeignKey(User, related_name="host_set")
class Meta:
constraints = [
models.UniqueConstraint(
fields=['migration', 'host'], name="unique_migration_host_combination"
)
]
Respuesta original
Implementaría esto de manera ligeramente diferente.
Usaría una clave principal predeterminada (campo automático) y usaría la propiedad de metaclase, unique_together
class Hop(models.Model):
migration = models.ForeignKey('Migration')
host = models.ForeignKey(User, related_name="host_set")
class Meta:
unique_together = (("migration", "host"),)
Actuaría como una columna de clave principal “sustituta”.
Si realmente desea crear una clave principal de varias columnas, investigue Esta aplicación
-
Si uso unique_together, ¿significa que no tengo que tener un campo establecido como clave principal?
– Connor
15 de enero de 2014 a las 19:18
-
Si no especifica un
AutoField
, django agregaría uno para ti. Así que en resumen, no lo haces.– Karthikr
15 de enero de 2014 a las 19:23
-
¿Sigue estando actualizado en 2018 con Django 2?
– NaturalBornCamper
27 de marzo de 2018 a las 1:28
-
Implementarías esto de manera diferente, pero no mencionas que lo harías porque Django no admite que la clave principal sea varios campos
– lince de fuego
5 de octubre de 2018 a las 8:04
-
Hubo una sugerencia de edición para Django 4.0. ¿Estaba bien o no?
-Peter Mortensen
7 mayo 2022 a las 12:43
Hùng Ng Vi
Actualmente, los modelos de Django solo admiten una clave principal de una sola columna. Si no especificas primary_key = True
para el campo en su modelo, Django creará automáticamente una columna id
como clave principal.
el atributo unique_together
en la clase Meta
es solo una restricción para sus datos.
pulord
Si debe usar Django en una base de datos heredada, no puede modificar esquema_db.
Hay un método alternativo (feo) para solucionar este problema:
Anular los modelos ahorrar o borrar función:
# Use a raw SQL statement to save or delete the object
class BaseModel(models.Model):
def get_max_length_unique_key(self):
max_len_unique_key = []
for unique_key in self._meta.unique_together:
if len(unique_key) > len(max_len_unique_key):
max_len_unique_key = unique_key
return max_len_unique_key
def get_db_conn(self):
db_cnn = DbManage(db_ip, db_port, DATABASES_USER, DATABASES_PASSWORD, self._meta.db_table)
db_cnn.connect()
return db_cnn
def save(self, *args, **kwargs):
self.delete()
cnn, databasename = self.get_db_conn()
update_tables = self._meta.db_table
key_list = ""
values_list = ""
for field in self._meta.fields:
key_list += "%s," % field.name
values_list += "\'%s\'," % str(getattr(self, field.name))
key_list = key_list[:len(key_list) - 1]
values_list = values_list[:len(values_list) - 1]
sql = "insert into %s(%s) values(%s)" % (update_tables, key_list, values_list)
logger.info("insert new record to %s" % databasename)
cnn.excute_sql(sql)
cnn.close()
def delete(self, *args, **kwargs):
cnn = self.get_db_conn()
update_tables = self._meta.db_table
sql = "delete from %s where " % update_tables
for uk in self.get_max_length_unique_key():
sql += "%s=\'%s\' and " % (uk, getattr(self, uk))
sql = sql[:len(sql) - 4]
logger.info("delete record from %s" % update_tables)
cnn.excute_sql(sql)
cnn.close()
pass
class Meta:
abstract = True
class ImageList(BaseModel):
field1 = models.CharField(primary_key=True, max_length=30)
field2 = models.CharField(primary_key=True, max_length=30)
field3 = models.CharField(primary_key=True, max_length=30)
body = models.CharField(max_length=2000, blank=True, null=True)
updated_on = models.DateTimeField(blank=True, null=True)
class Meta:
managed = True
db_table="image_list"
unique_together = (('field1', 'field2', 'field3'),)
Dado que la última versión de Django (4.0.4 en este momento) sugiere que el único_juntos puede ser obsoleto en el futurouna solución más actualizada sería usar el constraints
opción de la clase Meta junto con la UniqueConstraint
clase:
class Hop(models.Model):
migration = models.ForeignKey('Migration')
host = models.ForeignKey(User, related_name="host_set")
class Meta:
constraints = [
UniqueConstraint(fields=['migration', 'host'], name="unique_host_migration"),
]
posible duplicado stackoverflow.com/questions/4871966/…
– Paulo Bu
28 mayo 2013 a las 20:11