2010-07-13 13 views
205

मैं एक मॉडल में विशिष्ट फ़ील्ड के नाम बदलने के लिए करना चाहते हैं:Django - कैसे दक्षिण का उपयोग कर एक मॉडल क्षेत्र का नाम बदलने के लिए?

class Foo(models.Model): 
    full_name  = models.CharField() 
    odd_relation = models.ForeignKey(Bar) 

दक्षिण का उपयोग कर यह करने के लिए सबसे आसान तरीका क्या है:

class Foo(models.Model): 
    name = models.CharField() 
    rel = models.ForeignKey(Bar) 

को बदलना चाहिए?

+7

एक * मॉडल फ़ील्ड * के बजाए * मॉडल * का नाम बदलने के लिए http://stackoverflow.com/questions/2862979/easiest-way-to-rename-a-model-using-django-outh भी देखें। –

उत्तर

227

आप db.rename_column फ़ंक्शन का उपयोग कर सकते हैं।

class Migration: 

    def forwards(self, orm): 
     # Rename 'name' field to 'full_name' 
     db.rename_column('app_foo', 'name', 'full_name') 




    def backwards(self, orm): 
     # Rename 'full_name' field to 'name' 
     db.rename_column('app_foo', 'full_name', 'name') 

db.rename_column का पहला तर्क तालिका नाम है, इसलिए इसे याद करने के लिए कैसे Django creates table names महत्वपूर्ण है:

Django automatically derives the name of the database table from the name of your model class and the app that contains it. A model's database table name is constructed by joining the model's "app label" -- the name you used in manage.py startapp -- to the model's class name, with an underscore between them.

मामले में जहां एक बहु शब्दों में, ऊंट मामलों मॉडल का नाम है, इस तरह के ProjectItem के रूप में, टेबल नाम होगा app_projectitem (यानी, एक अंडरस्कोर project और item के बीच शामिल नहीं किया जाएगा, भले ही वे ऊंट मामलों हैं)।

+2

वह नाम \ full_name पर काम करेगा, लेकिन संबंध क्षेत्र पर नहीं, है ना? – Jonathan

+0

मैंने db.rename_column ('app_foo', 'rel', 'odd_relation') की कोशिश की और प्राप्त किया: _mysql_exceptions.OperationalError: (1025, "नाम बदलने में त्रुटि। \\ ap_site \\ # sql-1034_20 'to'। \\ my_app_db \\ app_foo '(errno: 150) ") – Jonathan

+0

यह पता चला है कि यह त्रुटि इसलिए है क्योंकि इस कॉलम को बंधे इंडेक्स (डीजेंगो ने अद्वितीय_एक साथ बाधा उत्पन्न की है)। किसी भी विचार से यहां कैसे जारी रहना है? – Jonathan

15

मुझे db.rename कॉलम के बारे में पता नहीं था, आसान लगता है, हालांकि अतीत में मैंने एक नया स्कीममैपेशन के रूप में नया कॉलम जोड़ा है, फिर नए क्षेत्र में मूल्यों को स्थानांतरित करने के लिए डेटामैपेशन बनाया है, फिर निकालने के लिए दूसरा स्कीमेशन पुराने कॉलम

+0

मुझे भी। स्कीमा-डेटा-स्कीमा तकनीक के साथ समस्या यह है कि आप अपने फ़ील्ड/मॉडल के लिए अलग-अलग नामों के साथ समाप्त होते हैं। कभी-कभी यह एक समस्या है यदि आप प्रेषक को सक्षम करने के लिए कैनोलिक नामों का उपयोग करते हैं ... – Jonathan

+0

मैंने अभी यह कोशिश की और यह काम नहीं किया क्योंकि नाम एक संघर्ष था। मेरे पास बिल्कुल वही एफके था लेकिन अलग-अलग नाम था। यह मान्य नहीं था। तो, _don't_ यह मत करो। – Gezim

+2

@ जोनाथन, वह अलग-अलग नाम चाहता है! ... @pilgrim, कुछ कोड पोस्ट करने की परवाह है?मैंने इस सप्ताह कई बार ऐसा किया है, यदि आपके मॉडल मान्य नहीं हैं तो दक्षिण में माइग्रेशन नहीं बनेंगे। – sjh

38

यहाँ मैं क्या करना है:

  1. अपने मॉडल में स्तंभ नाम परिवर्तन करें (इस उदाहरण में यह होगा myapp/models.py)
  2. भागो ./manage.py schemamigration myapp renaming_column_x --auto

नोट renaming_column_x कुछ भी आप की तरह हो सकता है, यह सिर्फ प्रवास फाइल करने के लिए एक विवरणात्मक नाम देने का एक तरीका है।

यह आपको myapp/migrations/000x_renaming_column_x.py नामक एक फ़ाइल जेनरेट करेगा जो आपके पुराने कॉलम को हटा देगा और एक नया कॉलम जोड़ देगा।

एक साधारण नाम बदलने के लिए प्रवास व्यवहार बदलने के लिए इस फ़ाइल में कोड को संशोधित करें:

class Migration(SchemaMigration): 

    def forwards(self, orm): 
     # Renaming column 'mymodel.old_column_name' to 'mymodel.new_column_name' 
     db.rename_column(u'myapp_mymodel', 'old_column_name', 'new_column_name') 

    def backwards(self, orm): 
     # Renaming column 'mymodel.new_column_name' to 'mymodel.old_column_name' 
     db.rename_column(u'myapp_mymodel', 'new_column_name', 'old_column_name') 
+0

आपके आदेश में कॉलम का नाम क्या है? 'x' या' column_x'? – andi

+0

जिस आदेश का आप जिक्र कर रहे हैं उसका हिस्सा सिर्फ माइग्रेशन नाम देने के लिए उपयोग किया जाता है, यह जो कुछ भी आपको पसंद हो सकता है। जब आप इसे संपादित करते हैं तो कॉलम नाम को माइग्रेशन फ़ाइल में निर्दिष्ट करने की आवश्यकता होगी। – donturner

+2

'--auto' माइग्रेशन पहले बनाना एक महान युक्ति है। यह दक्षिण ओआरएम फ्रीजर के साथ समस्याओं से बचाता है, जो तब होता है जब माइग्रेशन में केवल 'आगे' और 'पीछे की ओर' विधियां होती हैं, लेकिन इसमें जमे हुए 'मॉडल' ऑब्जेक्ट नहीं होता है। – mwcz

0
  1. परियोजना सेटिंग फ़ाइल में अपने इंस्टॉल किए गए एप्लिकेशन को south जोड़ें। बाहर जोड़ा/संशोधित क्षेत्र/तालिका
  2. टिप्पणी।
  3. $ manage.py Schemamigration <app_name> --initial
  4. $ manage.py migrate <app_name> --Fake
  5. संयुक्त राष्ट्र टिप्पणी क्षेत्र और संशोधित एक
  6. $ manage.py Schemamigration --auto
  7. $ manage.py migrate <app_name>

बारे में आप 'pycharm' का उपयोग कर रहे हैं, तो आप ctrl उपयोग कर सकते हैं '+ + आर 'के बजाय' manage.py ', और' मापदंडों के लिए पारी 'पाली।

9

Django 1.7 ने Migrations पेश किया है, इसलिए अब आपको अपने माइग्रेशन प्रबंधित करने के लिए अतिरिक्त पैकेज इंस्टॉल करने की आवश्यकता नहीं है।

अपने मॉडल का नाम बदलने के लिए आपको पहले खाली प्रवास बनाना होगा:

$ manage.py makemigrations <app_name> --empty 

तो फिर तुम इस तरह अपने माइग्रेशन के कोड को संपादित करने की जरूरत है:

from django.db import models, migrations 

class Migration(migrations.Migration): 

dependencies = [ 
    ('yourapp', 'XXXX_your_previous_migration'), 
] 

operations = [ 
    migrations.RenameField(
     model_name='Foo', 
     old_name='name', 
     new_name='full_name' 
    ), 
    migrations.RenameField(
     model_name='Foo', 
     old_name='rel', 
     new_name='odd_relation' 
    ), 
] 

और उसके बाद आप को चलाने के लिए की जरूरत है:

$ manage.py migrate <app_name> 
5

बस मॉडल बदल सकते हैं और makemigrations मैं चलाने n 1,9

Django स्वचालित रूप से पता लगाता है कि आप को नष्ट कर दिया है और एक ही क्षेत्र बनाया है, और पूछता है:

Did you rename model.old to model.new (a IntegerField)? [y/N] 

हाँ कहो, और सही प्रवास बनाया जाता है। जादू।

संबंधित मुद्दे