it-swarm.com.de

Wie kann ich zwei Primärschlüsselfelder für meine Modelle in Django einstellen?

Ich habe ein Modell wie dieses:

class Hop(models.Model):
    migration = models.ForeignKey('Migration')
    Host = models.ForeignKey(User, related_name='Host_set')

Ich möchte Migration und Host beides zusammen zum Primärschlüssel machen.

44
2 8

Ich würde das etwas anders umsetzen.

Ich würde einen Standardprimärschlüssel (automatisches Feld) verwenden und die Metaklasseneigenschaft unique_together Verwenden.

class Hop(models.Model):
    migration = models.ForeignKey('Migration')
    Host = models.ForeignKey(User, related_name='Host_set')

    class Meta:
        unique_together = (("migration", "Host"),)

Es würde als "Ersatz" -Primärschlüsselspalte fungieren.

Wenn Sie wirklich einen mehrspaltigen Primärschlüssel erstellen möchten, lesen Sie diese App

66
karthikr

Derzeit unterstützen Django Modelle nur einen einspaltigen Primärschlüssel. Wenn Sie kein bestimmtes primary_key = True Für das Feld in Ihrem Modell erstellt Django) automatisch eine Spalte id als Primärschlüssel.

Das Attribut unique_together in Klasse Meta ist nur Einschränkungen für Ihre Daten.

13
Hùng Ng Vi

wenn Sie Django für ältere Datenbanken verwenden, können Sie db_schema nicht ändern

es gibt eine (hässliche) Umgehungsmethode, um dieses Problem zu beheben

Override die Modelle speichern oder löschen Funktion

# 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'),)
2
pulord