Django: нулевое значение IntegrityError нарушает ограничение на ненулевое значение - PullRequest
0 голосов
/ 04 августа 2020

В моем приложении django происходит что-то странное, и я не понимаю.

У меня две разные таблицы ( employeeProfile & PurchaserShippingDetail ) у каждого есть поле с отношением OneToOneField, но с 1-й таблицей ( employeeProfile ) в поле user , который использует OneToOneField, я могу передать строковое представление, например, Michael с использованием api, и я не получаю ошибку, но в моей второй таблице, которая имеет аналогичную структуру, когда я добавляю строковое представление, я получаю

IntegrityError в / api / clients / shipping / null value в столбце "owner_id" нарушает ограничение не-null

1-я модель таблицы (работает нормально)


class employeeProfile(models.Model):
    image = models.ImageField(default='default.png',upload_to='employee_photos/%Y/%m/%d/')
    user = models.OneToOneField(CustomUser, on_delete=models.CASCADE, related_name="employee_profile")
    phone_no = models.CharField(max_length=10, unique=True)

    def __str__(self):
        return self.user.name

2-я табличная модель ( та, которая выдает «owner_id» нарушает ошибку ограничения not-null )

class purchaserShippingDetail(models.Model):

    frequent_customer = models.BooleanField(default=False)
    owner = models.OneToOneField(Purchaser, on_delete=models.CASCADE, related_name="purchaser_shipping")
    address = models.CharField(max_length=12, blank=True)
    zip_code = models.CharField(max_length=12, blank=True)
    location = models.CharField(max_length=255)

    def __str__(self):
        return self.owner.name

Покупатель Модель

class Purchaser(models.Model):
    name = models.CharField(max_length=50)
    phone = models.CharField(max_length=20, unique=True)
    email = models.EmailField(max_length=255, unique=True, blank=True)
    data_added = models.DateField(default=datetime.date.today)

    def __str__(self):
        return self.name

сериализатор для PurchaserShippingDetail модель

class purchaserShippingDetailSerializer(serializers.ModelSerializer):
    owner = serializers.StringRelatedField(read_only=True)
    class Meta:
        model = purchaserShippingDetail
        fields = '__all__'

Views.py для покупателя Ши ppingDetail model

class purchaserShippingDetailsListCreateView(ListCreateAPIView):

    serializer_class = purchaserShippingDetailSerializer
    queryset = purchaserShippingDetail.objects.all()

EDIT: Добавлена ​​таблица модели покупателя

1 Ответ

0 голосов
/ 04 августа 2020

Не могли бы вы выложить и модель Purchaser? Есть поле, на которое есть ссылка owner_id, которое мы не видим в вашем сообщении, что объясняет больше.

Добавляли ли вы поле владельца при недавней миграции? Возможно, вы добавляете поле, не допускающее значения NULL, в таблицу с существующими строками, в результате чего эти строки не удовлетворяют условию, не допускающему значения NULL.

Вы не можете добавить значение по умолчанию в OneToOneField, поэтому в этом случае вам нужно сначала добавить поле как null=True. Затем создайте пустой файл миграции, чтобы создать экземпляры всех строк в этой таблице, чтобы ни одна из строк не имела нулевого значения. Обычно вы делаете это с помощью manage.py makemigrations app_name --empty.

Этот файл может выглядеть примерно так:

from django.db import migrations

def instantiate_owner(apps, schema_editor):
    purchaserShippingDetail = apps.get_model("appname", "purchaserShippingDetail")
    Purchaser = apps.get_model("some_other_app", "Purchaser")

    for detail in purchaserShippingDetail.objects.all():
      owner = Purchaser.objects.get(some_unique_criteria=detail.unique_criteria)
      detail.owner = owner
      detail.save()


class Migration(migrations.Migration):

    dependencies = [
       ...,
    ]

    operations = [
        migrations.RunPython(instantiate_owner),
    ]

После этого вы можете удалить null=True в своей модели и выполнить еще одну миграцию.

...