首页 > 解决方案 > Django RF - 以'0'开头的主键字符字段导致POST上的IntegrityError?

问题描述

我最近对我正在开发的项目进行了一些更改,我必须将模型的主键从它的默认 Django 分配值更改为将在生产中使用的代码。

在测试项目前端(在 Angular 中开发)时,我注意到一个内部服务器错误,该错误仅在尝试发布所述模型时产生,而它的代码以“0”开头。我认为这与它在内部试图将其解析为“601”而不是“0601”但不知道为什么、如何或在何处发生这种情况有关。

为了更好地说明,这些是正在使用的代码。注意我使用serializers.HyperlinkedModelSerializer的是 Django REST Framework,这就是为什么它们values是 url 格式的。即使我尝试直接从 API 视图(从中获取此 html 代码)进行 POST,问题仍然存在。如果我选择一个代码以 0 开头的值,我会得到:

市政厅

所有 id 以“1”开头的 url 都会产生成功的 POST,但是如果我选择一个 id 以 0 开头的值,我会得到以下回溯

Traceback (most recent call last):
  File "C:\Users\JOSEAN~1\VIRTUA~1\SIRS-R~1\lib\site-packages\django\core\handlers\exception.py", line 34, in inner
    response = get_response(request)
  File "C:\Users\JOSEAN~1\VIRTUA~1\SIRS-R~1\lib\site-packages\django\core\handlers\base.py", line 115, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "C:\Users\JOSEAN~1\VIRTUA~1\SIRS-R~1\lib\site-packages\django\core\handlers\base.py", line 113, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "C:\Users\JOSEAN~1\VIRTUA~1\SIRS-R~1\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
    return view_func(*args, **kwargs)
  File "C:\Users\JOSEAN~1\VIRTUA~1\SIRS-R~1\lib\site-packages\django\views\generic\base.py", line 71, in view
    return self.dispatch(request, *args, **kwargs)
  File "C:\Users\JOSEAN~1\VIRTUA~1\SIRS-R~1\lib\site-packages\rest_framework\views.py", line 505, in dispatch
    response = self.handle_exception(exc)
  File "C:\Users\JOSEAN~1\VIRTUA~1\SIRS-R~1\lib\site-packages\rest_framework\views.py", line 465, in handle_exception
    self.raise_uncaught_exception(exc)
  File "C:\Users\JOSEAN~1\VIRTUA~1\SIRS-R~1\lib\site-packages\rest_framework\views.py", line 476, in raise_uncaught_exception
    raise exc
  File "C:\Users\JOSEAN~1\VIRTUA~1\SIRS-R~1\lib\site-packages\rest_framework\views.py", line 502, in dispatch
    response = handler(request, *args, **kwargs)
  File "C:\Users\JOSEAN~1\VIRTUA~1\SIRS-R~1\lib\site-packages\rest_framework\generics.py", line 190, in post
    return self.create(request, *args, **kwargs)
  File "C:\Users\JOSEAN~1\VIRTUA~1\SIRS-R~1\lib\site-packages\rest_framework\mixins.py", line 19, in create
    self.perform_create(serializer)
  File "C:\Users\JOSEAN~1\VIRTUA~1\SIRS-R~1\lib\site-packages\rest_framework\mixins.py", line 24, in perform_create
    serializer.save()
  File "C:\Users\JOSEAN~1\VIRTUA~1\SIRS-R~1\lib\site-packages\rest_framework\serializers.py", line 212, in save
    self.instance = self.create(validated_data)
  File "C:\Users\JOSEAN~1\VIRTUA~1\SIRS-R~1\lib\site-packages\rest_framework\serializers.py", line 948, in create
    instance = ModelClass._default_manager.create(**validated_data)
  File "C:\Users\JOSEAN~1\VIRTUA~1\SIRS-R~1\lib\site-packages\django\db\models\manager.py", line 82, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "C:\Users\JOSEAN~1\VIRTUA~1\SIRS-R~1\lib\site-packages\django\db\models\query.py", line 433, in create
    obj.save(force_insert=True, using=self.db)
  File "C:\Users\JOSEAN~1\VIRTUA~1\SIRS-R~1\lib\site-packages\django\db\models\base.py", line 745, in save
    self.save_base(using=using, force_insert=force_insert,
  File "C:\Users\JOSEAN~1\VIRTUA~1\SIRS-R~1\lib\site-packages\django\db\models\base.py", line 782, in save_base
    updated = self._save_table(
  File "C:\Users\JOSEAN~1\VIRTUA~1\SIRS-R~1\lib\site-packages\django\db\models\base.py", line 886, in _save_table
    results = self._do_insert(cls._base_manager, using, fields, returning_fields, raw)
  File "C:\Users\JOSEAN~1\VIRTUA~1\SIRS-R~1\lib\site-packages\django\db\models\base.py", line 923, in _do_insert
    return manager._insert(
  File "C:\Users\JOSEAN~1\VIRTUA~1\SIRS-R~1\lib\site-packages\django\db\models\manager.py", line 82, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "C:\Users\JOSEAN~1\VIRTUA~1\SIRS-R~1\lib\site-packages\django\db\models\query.py", line 1204, in _insert
    return query.get_compiler(using=using).execute_sql(returning_fields)
  File "C:\Users\JOSEAN~1\VIRTUA~1\SIRS-R~1\lib\site-packages\django\db\models\sql\compiler.py", line 1377, in execute_sql
    cursor.execute(sql, params)
  File "C:\Users\JOSEAN~1\VIRTUA~1\SIRS-R~1\lib\site-packages\django\db\backends\utils.py", line 100, in execute
    return super().execute(sql, params)
  File "C:\Users\JOSEAN~1\VIRTUA~1\SIRS-R~1\lib\site-packages\django\db\backends\utils.py", line 68, in execute
    return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
  File "C:\Users\JOSEAN~1\VIRTUA~1\SIRS-R~1\lib\site-packages\django\db\backends\utils.py", line 77, in _execute_with_wrappers
    return executor(sql, params, many, context)
  File "C:\Users\JOSEAN~1\VIRTUA~1\SIRS-R~1\lib\site-packages\django\db\backends\utils.py", line 86, in _execute
    return self.cursor.execute(sql, params)
  File "C:\Users\JOSEAN~1\VIRTUA~1\SIRS-R~1\lib\site-packages\django\db\utils.py", line 90, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "C:\Users\JOSEAN~1\VIRTUA~1\SIRS-R~1\lib\site-packages\django\db\backends\utils.py", line 86, in _execute
    return self.cursor.execute(sql, params)
  File "C:\Users\JOSEAN~1\VIRTUA~1\SIRS-R~1\lib\site-packages\django\db\backends\sqlite3\base.py", line 396, in execute
    return Database.Cursor.execute(self, query, params)
django.db.utils.IntegrityError: FOREIGN KEY constraint failed

市政模型:

class Municipio(models.Model):
    codigo_departamento = models.ForeignKey(
        Departamento, on_delete=models.CASCADE)
    codigo_municipio = models.CharField(max_length=4,primary_key=True)
    municipio = models.TextField(max_length=50)

    def __str__(self):
        return self.municipio

    class Meta:
        constraints = [
            models.UniqueConstraint(
                fields=[
                    'codigo_departamento',
                    'codigo_municipio'
                ],
                name='unique_codigo')
        ]

EncuestaHogar 模型(IntegrityError 来自 POSTing this):

class EncuestaHogar(models.Model):
    encuesta = models.OneToOneField(
        Encuesta,
        on_delete=models.CASCADE,
        primary_key=True,
    )
    nombre_encuestador = models.TextField(max_length=50)
    numero_boleta = models.IntegerField(unique=True)
    colonia = models.TextField(max_length=50, null=True, blank=True)
    barrio = models.TextField(max_length=50, null=True, blank=True)
    aldea = models.TextField(max_length=50, null=True, blank=True)
    caserio = models.TextField(max_length=50, null=True, blank=True)
    nombre_entrevistado = models.TextField(max_length=50)
    celular = models.CharField(max_length=9, null=True, blank=True)
    numero_ubicacion = models.IntegerField()
    codigo_municipio = models.ForeignKey(Municipio, on_delete=models.CASCADE)

正在使用的序列化器:

class MunicipioSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Municipio
        fields = '__all__'

class EncuestaHogarSerializerW(serializers.HyperlinkedModelSerializer):
    encuesta = serializers.HyperlinkedRelatedField(
        view_name='encuesta-detail', queryset=Encuesta.objects.all())

    class Meta:
        model = EncuestaHogar
        fields = ['encuesta', 'nombre_encuestador', 'numero_boleta', 'colonia', 'barrio',
                  'aldea', 'caserio', 'nombre_entrevistado', 'celular', 'numero_ubicacion', 'codigo_municipio']

看法:

class EncuestaHogarAddView(generics.CreateAPIView):
    queryset = EncuestaHogar.objects.all()
    serializer_class = EncuestaHogarSerializerW

标签: pythondjangoangulardjango-rest-framework

解决方案


检查 TraceBack 上的变量值后,我注意到前导 0 被保留,所以我转向数据库并找到了罪魁祸首。

在此处输入图像描述

我认为即使在我修改了 FK 之后,它仍将其旧数据类型保留为 INTEGER


推荐阅读