2014-10-03 22 views
44

olmadan kullanıcı profiline null olmayan bir 'new_field' alanı eklemeyi denedim Django 1.7'den Güney veya başka bir geçiş sistemini kullanmam gerektiğini biliyorum, bu yüzden sadece basit bir komut kullanıyorum python manage.py makemigrationsVarsayılan olarak

Ancak, ben olsun tüm bu hatadır:

İşte
You are trying to add a non-nullable field 'new_field' to userprofile without a default; 
we can't do that (the database needs something to populate existing rows). 

olduğunu models.py:

class UserProfile(models.Model): 
    user = models.OneToOneField(User) 
    website = models.URLField(blank=True) 
    new_field = models.CharField(max_length=140) 

seçenekleri nelerdir?

new_field = models.CharField(max_length=140, default='SOME STRING') 
+2

Yeni bir tane oluştururken değil, varolan tabloyu değiştirdiğinizde sorun oluştuğunu eklemek istedim. –

cevap

37

Varsayılan bir değer sağlamanız gerekir.

class UserProfile(models.Model): 
    user = models.OneToOneField(User) 
    website = models.URLField(blank=True, default='DEFAULT VALUE') 
    new_field = models.CharField(max_length=140, blank=True, default='DEFAULT VALUE') 

    def save(self, *args, **kwargs): 
     if not self.new_field: 
      # Setting the value of new_field with website's value 
      self.new_field = self.website 

     # Saving the object with the default save() function 
     super(UserProfile, self).save(*args, **kwargs) 
+0

Yeni bir web sitesi alanının kopyasına sahip olmam gerekirse. Nasıl görünmeli? 'default = web sitesi' işi yapmaz –

+4

İlk olarak, sahte bir varsayılan değerle geçişi yapmak ve ardından [veri taşıma] oluşturmak istersiniz (https://docs.djangoproject.com/en/1.7/topics/migrations/# veri geçişi) her kayıtta yinelemeli ve 'new_field''i' website' olarak ayarlamalıdır. – dgel

4

"web sitesi" Eğer new_field da boş olduğu ayarlanmalıdır daha boş olabilir:

21

Bir: Şimdi new_field "web sitesi" değeri kapmak için boşsa nerede tasarrufu üzerine mantığı eklemek istiyorsanız

yapmanız gereken hepsi böyle senin Model için kaydetme fonksiyonu geçersiz olduğunu

:

new_field = models.CharField(max_length=140, default='DEFAULT VALUE') 

başka bir seçenek null bir alan olarak 'new_field' ilan etmektir: seçeneği 'new_field' için varsayılan bir değer beyan etmektir

'new_field' öğesini null olmayan bir alan olarak kabul etmeye karar verirseniz, 'new_field' için 'input yok' değerini geçerli giriş olarak kabul etmek isteyebilirsiniz. Sonra siz de blank=True ifadeyi eklemek zorunda:

new_field = models.CharField(max_length=140, blank=True, null=True) 

bile null=True ve/veya birlikte blank=True gerekirse varsayılan bir değer ekleyebilirsiniz: new_file olarak

new_field = models.CharField(max_length=140, default='DEFAULT VALUE', blank=True, null=True) 
+0

«CharField ve TextField gibi dize tabanlı alanlarda null kullanmaktan kaçının. Dize tabanlı bir alan null = True ise, bunun anlamı “veri yok” için iki olası değere sahip olmasıdır: NULL ve boş dize. »- [Model alanı referansı] (https://docs.djangoproject.com/en/dev/ref/models/fields/# null) – Chema

2

boolean mülkiyet null adlı ekleyin.

new_field = models.CharField(max_length=140, null=True) 

Eğer DB yenilemek için ./manage.py syncdb çalıştırdıktan sonra. ve nihayet ./manage.py makemigrations ve

38

erken gelişim döngüsünde ve mevcut veritabanı veri hakkında umurumda değil sadece kaldırabilirsiniz ise ve göç daha ./manage.py migrate çalıştırın. Ama önce zaten tabloda UserProfile veritabanı girdileri var mı

rm your_app/migrations/* 

rm db.sqlite3 
python manage.py makemigrations 
python manage.py migrate 
+4

Bir şey daha. Geçişler tablo temizlemek gerekir. Örn: 'mysql -u [kullanıcı] [veritabanı] -e" django_migrations silin app nerede = [your_app] "' – helpse

+0

Ben windows kullanıyorum ve rm çalışmıyor. –

+0

Bu yoldur. Bence Django, göç ve model tespiti, vb. Berbat. Bunun için büyük bir güncelleme istiyorum. – FaithReaper

2

dir geçişleri temizlemek gerekir? Eğer öyleyse, yeni sütunlar eklediğinizde, DB NULL olamayacağı için neyi ayarlayacağını bilmemektedir. Bu nedenle, new_fields sütununda bu alanları ayarlamak istediğinizi sorar. Sorunu çözmek için bu tablodaki tüm satırları silmem gerekiyordu.

bu durumdan Django belge dan yöntemi kullanabilirsiniz

+0

Tabloya satır eklemedim ve yine de bunu aldım. Tomasz'ın önerdiği gibi, tüm göç geçmişini, modeli değiştirmek için göç tablosunu silmem gerekiyor. – FaithReaper

2

(Umarım bunu görür yeni kimseye yardımcı olacaktır. Bu bir süre önce cevap verilmiştir biliyorum ama sadece bu sorunla karşılaştık ve bu benim çözüm oldu) sayfa https://docs.djangoproject.com/en/1.8/ref/models/fields/#default

varsayılan oluşturun ve erken gelişme döngüsü içine ise bunun

def contact_default(): 
    return {"email": "[email protected]"} 

contact_info = JSONField("ContactInfo", default=contact_default) 
2

bu deneyebilirsiniz kullanmak -

Bu modeli ve tüm kullanımlarını kaldırın/yorumlayın. Göçler uygula. Bu modeli siler ve daha sonra modeli tekrar ekler, geçişleri çalıştırır ve yeni alan eklendiğinde temiz bir modeliniz olur. Django aslında ne diyor

0

geçerli:

Eğer userprofile tablodaki değerlerin hiçbiri NULL eminseniz

Userprofile table has data in it and there might be new_field values which are null, but I do not know, so are you sure you want to mark property as non nullable, because if you do you might get an error if there are values with NULL

- bedava düştü ve uyarıyı görmezden.

bu tür durumlarda en iyi yöntem boş new_field değerle tüm UserProfile örneklerini bulmak zorunda ve koyun o RunPython taşımada seçenek 2

2) Ignore for now, and let me handle existing rows with NULL myself (e.g. because you added a RunPython or RunSQL operation to handle NULL values in a previous data migration)

belirttiği gibi boş değerler işlemek için bir RunPython göç yaratmak olacaktır Burada doğru bir değer (veya Django'nun modelde ayarlamanızı istediği varsayılan bir değer). Böyle bir şey alacak:

# please keep in mind that new_value can be an empty string. You decide whether it is a correct value. 
for profile in UserProfile.objects.filter(new_value__isnull=True).iterator(): 
    profile.new_value = calculate_value(profile) 
    profile.save() # better to use batch save 

eğlenceler!

İlgili konular