यो लोग,
मैं मैं चाहता था बनाने में कामयाब रहे।
पहले, मैं एक नए क्षेत्र बनाया:
from django.db.models.deletion import DO_NOTHING
from django.db.models.fields.related import ForeignKey, ManyToOneRel
class SoftForeignKey(ForeignKey):
"""
This field behaves like a normal django ForeignKey only without hard database constraints.
"""
def __init__(self, to, to_field=None, rel_class=ManyToOneRel, **kwargs):
ForeignKey.__init__(self, to, to_field=to_field, rel_class=rel_class, **kwargs)
self.on_delete = DO_NOTHING
no_db_constraints = True
जब से मैं दक्षिण का उपयोग अपने डेटाबेस स्कीमा का प्रबंधन करने, मैं इस जोड़ने के लिए किया था:
from south.modelsinspector import add_introspection_rules
add_introspection_rules([], [r'^ecm\.lib\.softfk\.SoftForeignKey'])
फिर, मैं बंदर पड़ा पैच दक्षिण ताकि यह no_db_constraints
पैरामीटर खाते में ले जाए।
from django.db.models.deletion import DO_NOTHING
from django.db.models.fields.related import ForeignKey, ManyToOneRel
from django.core.management.color import no_style
from south.db.generic import DatabaseOperations, invalidate_table_constraints, flatten
def column_sql(self, table_name, field_name, field, tablespace='', with_name=True, field_prepared=False):
"""
Creates the SQL snippet for a column. Used by add_column and add_table.
"""
# If the field hasn't already been told its attribute name, do so.
...
...
...
if field.rel and self.supports_foreign_keys:
# HACK: "soft" FK handling begin
if not hasattr(field, 'no_db_constraints') or not field.no_db_constraints:
self.add_deferred_sql(
self.foreign_key_sql(
table_name,
field.column,
field.rel.to._meta.db_table,
field.rel.to._meta.get_field(field.rel.field_name).column
)
)
# HACK: "soft" FK handling end
# Things like the contrib.gis module fields have this in 1.1 and below
if hasattr(field, 'post_create_sql'):
for stmt in field.post_create_sql(no_style(), ta
....
....
# monkey patch South here
DatabaseOperations.column_sql = column_sql
और::
from django.db.models.deletion import DO_NOTHING
from django.db.models.fields.related import ForeignKey, ManyToOneRel
from django.core.management.color import no_style
from south.db.generic import DatabaseOperations, invalidate_table_constraints, flatten
@invalidate_table_constraints
def alter_column(self, table_name, name, field, explicit_name=True, ignore_constraints=False):
"""
Alters the given column name so it will match the given field.
Note that conversion between the two by the database must be possible.
Will not automatically add _id by default; to have this behavour, pass
explicit_name=False.
@param table_name: The name of the table to add the column to
@param name: The name of the column to alter
@param field: The new field definition to use
"""
if self.dry_run:
if self.debug:
...
...
if not ignore_constraints:
# Add back FK constraints if needed
if field.rel and self.supports_foreign_keys:
# HACK: "soft" FK handling begin
if not hasattr(field, 'no_db_constraints') or not field.no_db_constraints:
self.execute(
self.foreign_key_sql(
table_name,
field.column,
field.rel.to._meta.db_table,
field.rel.to._meta.get_field(field.rel.field_name).column
)
)
# HACK: "soft" FK handling end
# monkey patch South here
DatabaseOperations.alter_column = alter_column
यह वास्तव में बदसूरत है, लेकिन मैं एक और तरीका भी नहीं मिला वहाँ दो कार्यों FK की कमी के निर्माण में शामिल थे।
अब आप सामान्य विदेशीकी की तरह सॉफ़्टफोइनकी फ़ील्ड का उपयोग कर सकते हैं सिवाय इसके कि आपके पास कोई रेफरेंसियल अखंडता प्रवर्तन नहीं होगा।
पूरा बंदर-पैच के लिए यहाँ देखें: http://eve-corp-management.org/projects/ecm/repository/entry/ecm/lib/softfk.py
यह वास्तव में एक विदेशी कुंजी नहीं है, innit? –
वैसे मैं डीबी बाधा के बिना django ForeignKey की सभी सुविधाओं से लाभ उठाना चाहता हूं। – Robin
उदाहरण के लिए, मैं 'SoftForeignKey' द्वारा संदर्भित तालिका से एक पंक्ति को हटाने के लिए सक्षम होना चाहता हूं, बिना कुंजी को 'कैलड या सेट' किए बिना। और यदि किसी ऑब्जेक्ट में लक्ष्य तालिका में एक गैर-मौजूदा पंक्ति का संदर्भ है, तो उसे 'ऑब्जेक्टडिज़ नॉटएक्सिस्ट' अपवाद उठाना चाहिए। लेकिन मैं डेटाबेस को इस तरह के राज्य को स्वीकार करना चाहता हूं। – Robin