J'ai un modèle comme celui-ci:
class Hop(models.Model):
migration = models.ForeignKey('Migration')
Host = models.ForeignKey(User, related_name='Host_set')
Je veux que la migration et l'hôte soient ensemble la clé primaire.
Je mettrais cela en œuvre légèrement différemment.
J'utiliserais une clé primaire par défaut (champ automatique) et j'utiliserais la propriété de la méta classe, unique_together
class Hop(models.Model):
migration = models.ForeignKey('Migration')
Host = models.ForeignKey(User, related_name='Host_set')
class Meta:
unique_together = (("migration", "Host"),)
Il agirait comme une colonne de clé primaire "de substitution".
Si vous voulez vraiment créer une clé primaire multi-colonnes, regardez dans cette application
Actuellement, Django ne prennent en charge qu'une seule clé primaire de colonne. Si vous ne spécifiez pas primary_key = True
pour le champ de votre modèle, Django créera automatiquement une colonne id
comme clé primaire.
L'attribut unique_together
dans la classe Meta
n'est que des contraintes pour vos données.
si vous devez utiliser Django sur la base de données héritée, vous ne pouvez pas modifier db_schema
il existe une méthode de contournement (laide) pour résoudre ce problème
override les modèles enregistrent ou suppriment la fonction
# use raw sql statement to save or delete 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'),)