I have a model like this:
我有一个这样的模型:
class Hop(models.Model):
migration = models.ForeignKey('Migration')
host = models.ForeignKey(User, related_name='host_set')
I want to migration and host both together be primary key.
我想要迁移和主机都是主键。
3 个解决方案
#1
47
I would implement this slightly differently.
我将以稍微不同的方式实现它。
I would use a default primary key (auto field), and use the meta class property, unique_together
我将使用默认的主键(auto field),并使用meta类属性unique_together
class Hop(models.Model):
migration = models.ForeignKey('Migration')
host = models.ForeignKey(User, related_name='host_set')
class Meta:
unique_together = (("migration", "host"),)
It would act as a "surrogate" primary key column.
它将充当“代理”主键列。
If you really want to create a multi-column primary key, look into this app
如果您真的想要创建一个多列主键,请查看这个应用程序。
#2
6
Currently, Django models only support a single column primary-key. If you don't specific primary_key = True
for the field in your model, Django will automatically create a column id
as a primary key.
目前,Django模型只支持单个列主键。如果您没有为模型中的字段指定primary_key = True, Django将自动创建一个列id作为主键。
The attribute unique_together
in class Meta
is only constraints for your data.
class Meta中的unique_together属性仅是数据的约束。
#3
0
if you should use django on legacy database, you can't modify db_schema
如果应该在遗留数据库上使用django,则不能修改db_schema
there is a workaround (ugly) method to fix this issue
有一个解决(丑陋的)方法来解决这个问题
override the models save or delete function
覆盖模型保存或删除功能
use raw sql statement to save or delete object
使用原始sql语句保存或删除对象
class BaseModel(models.Model):
类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):
类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'),)
#1
47
I would implement this slightly differently.
我将以稍微不同的方式实现它。
I would use a default primary key (auto field), and use the meta class property, unique_together
我将使用默认的主键(auto field),并使用meta类属性unique_together
class Hop(models.Model):
migration = models.ForeignKey('Migration')
host = models.ForeignKey(User, related_name='host_set')
class Meta:
unique_together = (("migration", "host"),)
It would act as a "surrogate" primary key column.
它将充当“代理”主键列。
If you really want to create a multi-column primary key, look into this app
如果您真的想要创建一个多列主键,请查看这个应用程序。
#2
6
Currently, Django models only support a single column primary-key. If you don't specific primary_key = True
for the field in your model, Django will automatically create a column id
as a primary key.
目前,Django模型只支持单个列主键。如果您没有为模型中的字段指定primary_key = True, Django将自动创建一个列id作为主键。
The attribute unique_together
in class Meta
is only constraints for your data.
class Meta中的unique_together属性仅是数据的约束。
#3
0
if you should use django on legacy database, you can't modify db_schema
如果应该在遗留数据库上使用django,则不能修改db_schema
there is a workaround (ugly) method to fix this issue
有一个解决(丑陋的)方法来解决这个问题
override the models save or delete function
覆盖模型保存或删除功能
use raw sql statement to save or delete object
使用原始sql语句保存或删除对象
class BaseModel(models.Model):
类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):
类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'),)