简体   繁体   中英

Django RF - Primary key char field starting with '0' causing IntegrityError on POST?

I recently made some changes to a project I'm developing where I had to change a model's primary key from it's default Django assigned value to a code that will be used in production.

When testing the projects front end (developed in Angular) I noticed an internal server error that was only produced when trying to POST said model when it's code started with a '0'. I believe it has something to do with the fact that internally its trying to parse it down to '601' instead of '0601' but have no idea why, how or where this is taking place.

To better illustrate, these are the codes being used. Note I am using serializers.HyperlinkedModelSerializer from Django REST Framework, which is why the values are in url format. The problem presists even if I try to POST directly from the API View (from which this html code is taken). If I select a value with a code starting in 0, I get:

市政厅

All urls with ids starting in '1' produce successful POSTs, however if I select a value with an id starting in 0, I get the following traceback

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

Municipio model:

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 model (IntegrityError comes from 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)

Serializers being used:

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']

View:

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

After checking variable values on the TraceBack I noticed the leading 0s were being preserved, so I turned to the DB and found the culprit.

在此处输入图片说明

I assume it retained its old datatype as INTEGER even after I modified the FKs

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM