developer tip

기본값없이 사용자 프로필에 nullable이 아닌 필드 'new_field'를 추가하려고합니다.

optionbox 2020. 9. 24. 07:45
반응형

기본값없이 사용자 프로필에 nullable이 아닌 필드 'new_field'를 추가하려고합니다.


Django 1.7부터 South 또는 다른 마이그레이션 시스템을 사용할 필요가 없다는 것을 알고 있으므로 간단한 명령을 사용하고 있습니다. python manage.py makemigrations

그러나 내가 얻는 것은이 오류입니다.

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).

다음은 models.py입니다.

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

옵션은 무엇입니까?


기본값을 제공해야합니다.

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

경우 는 초기 개발주기에 있고 상관 없어 현재에 대한 데이터베이스 데이터 당신은 그것을 제거하고 마이그레이션 할 수 있습니다. 하지만 먼저 마이그레이션 디렉터리를 정리하고 테이블 (django_migrations)에서 해당 행을 제거해야합니다.

rm  your_app/migrations/*

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

한 가지 옵션은 'new_field'에 대한 기본값을 선언하는 것입니다.

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

또 다른 옵션은 'new_field'를 nullable 필드로 선언하는 것입니다.

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

'new_field'를 nullable 필드로 허용하기로 결정한 경우 'new_field'에 대한 유효한 입력으로 '입력 없음'을 허용 할 수 있습니다. 그런 다음 blank=True문도 추가해야 합니다.

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

심지어와 null=True및 / 또는 blank=True필요한 경우에는 기본 값을 추가 할 수 있습니다 :

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

"웹 사이트"가 비어있을 수 있으면 비어있는 new_field것으로 설정해야합니다.

이제 new_field"website"에서 값을 가져 오기 위해 비어 있는 경우 저장에 논리를 추가 하려면 다음 Model과 같이 저장 기능을 재정의 하면됩니다.

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)

개발주기의 초기 단계라면 이것을 시도해 볼 수 있습니다.

해당 모델과 모든 사용법을 제거 / 주석하십시오. 마이그레이션을 적용합니다. 그러면 해당 모델이 삭제되고 모델이 다시 추가되고 마이그레이션이 실행되고 새 필드가 추가 된 깨끗한 모델이 생성됩니다.


In new_file add the boolean property null.

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

after you run a ./manage.py syncdb for refresh the DB. and finally you run ./manage.py makemigrations and ./manage.py migrate


You can use method from Django Doc from this page https://docs.djangoproject.com/en/1.8/ref/models/fields/#default

Create default and use it

def contact_default():
   return {"email": "to1@example.com"}

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

Do you already have database entries in the table UserProfile? If so, when you add new columns the DB doesn't know what to set it to because it can't be NULL. Therefore it asks you what you want to set those fields in the column new_fields to. I had to delete all the rows from this table to solve the problem.

(I know this was answered some time ago, but I just ran into this problem and this was my solution. Hopefully it will help anyone new that sees this)


I honestly fount the best way to get around this was to just create another model with all the fields that you require and named slightly different. Run migrations. Delete unused model and run migrations again. Voila.


What Django actually says is:

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

If you are sure that none of values in the userprofile table are NULL - fell free and ignore the warning.

The best practice in such cases would be to create a RunPython migration to handle empty values as it states in option 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)

In RunPython migration you have to find all UserProfile instances with empty new_field value and put a correct value there (or a default value as Django asks you to set in the model). You will get something like this:

# 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

Have fun!


You can't add reference to table that have already data inside.
Change:

user = models.OneToOneField(User)

to:

user = models.OneToOneField(User, default = "")

do:

python manage.py makemigrations
python manage.py migrate

change again:

user = models.OneToOneField(User)

do migration again:

python manage.py makemigrations
python manage.py migrate

If the SSH it gives you 2 options, choose number 1, and put "None". Just that...for the moment.

참고URL : https://stackoverflow.com/questions/26185687/you-are-trying-to-add-a-non-nullable-field-new-field-to-userprofile-without-a

반응형