1

this is another UnicodeDecodeError I'm dealing with in django. I can't find the way to solve it.

I'm trying to create an object:

nivel_obj = Nivel.objects.filter(id=nivel_id)
nueva_matricula = Matricula(nivel=nivel_obj, ano_lectivo=ano_lectivo, alumno=a)
nueva_matricula.save()

The "Matricula" object has a "nivel_obj" that is a Foreign Key. The "nivel_obj" has a name that is a string that could not be encoded/decoded.

How can I solve this?

These are the models:

class Nivel(models.Model):
    """
    Ej - "Octavo de Basica, 6to Curso"
    """
    nombre = models.CharField(max_length=150)

    class Meta:
        verbose_name_plural = "niveles"

    def __unicode__(self):
        return u"%s" % (self.nombre)


class Matricula(models.Model):
    ano_lectivo = models.PositiveIntegerField(validators=[MaxValueValidator(9999)])
    alumno = models.ForeignKey(Alumno)
    nivel = models.ForeignKey(Nivel, null=True) <----
    status = models.CharField(max_length=150, choices=(("A", "Activo"), ("I", "Inactivo")))

    def validate_unique(self, exclude=None):
        if Matricula.objects.filter(alumno=self.alumno, nivel=self.nivel, ano_lectivo=self.ano_lectivo).exists():
            error = u'Ya existe una matrícula igual, por favor revisa el año, el nivel y el alumno'
            raise ValidationError({NON_FIELD_ERRORS: error})
        else:
            pass

    class Meta:
        verbose_name_plural = "matrículas"
        verbose_name = "matrícula"

        ordering = ("alumno",)

    def __unicode__(self):
        return u"Matricula %s %s" % (self.alumno, self.ano_lectivo)

The exact error comes from a "Nivel" object that has a name like this "Octavo de Básica", I can't work with it without having a UnicodeDecodeError.

This is the error:

UnicodeDecodeError at /sisacademico/matricular_grupo/

'ascii' codec can't decode byte 0xc3 in position 20: ordinal not in range(128)

...

The string that could not be encoded/decoded was: de B��sica

EDIT: Found the Error

OK I found my error, I'm not going to delete the question cause the error (UnicodeDecodeError) django was giving me is completely misleading. The error was this one:

nivel_obj = Nivel.objects.filter(id=nivel_id) <---
nueva_matricula = Matricula(nivel=nivel_obj, ano_lectivo=ano_lectivo, alumno=a)

I cannot save a new object with a nivel=queryset and not nivel=NivelObject.

it should be:

nivel_obj = Nivel.objects.get(id=nivel_id)

My mistake.

BUT, WHY ON EARTH would django give me a UnicodeDecodeError?!!

1
  • Generally it all looks correct to me. You should use Unicode literals for your verbose_name attributes on Matricula, eg verbose_name = u'matrícula', but I don't see why that would create the exception you're seeing. UnicodeDecodeError comes from trying to mix encoded strings and Unicode objects when the encoded string contains non-ascii characters, eg 'matr\xc3\xadcula' + u'matrícula', so something somewhere is getting an encoded version of the name. Django doesn't do that on its own - I or other readers might be able to help spot it if you can show your view code. Commented Jun 17, 2015 at 20:00

2 Answers 2

1

filter isn't doing what you want it to here:

nivel_obj = Nivel.objects.filter(id=nivel_id)

filter returns a queryset, not a single object. You can't use it as the value of the ForeignKey field. I don't yet see why that would raise the exception you're reporting, maybe something not stringifying correctly while it's trying to report the exception?

Normally you'd use get to get a single object rather than a queryset, or in a view sometimes the get_object_or_404 shortcut. But you don't need to do that just to set a foreign key relationship - you can instantiate directly with the ID value:

nueva_matricula = Matricula(nivel_id=nivel_id, ano_lectivo=ano_lectivo, alumno=a)
nueva_matricula.save()

If your error persists, I would focus on checking the return type of self.nombre. Django CharFields should always return a Unicode object, but if you've got something really nonstandard happening and you're getting an encoded bytestring as nombre, your __unicode__ method will throw the UnicodeDecodeError shown. But that shouldn't be possible with standard Django.

Sign up to request clarification or add additional context in comments.

2 Comments

you're right, I was writing that last edit the moment you answered. I'll accept this answer, but the question of why the UnicodeDecodeError is still there. Thnx.
Probably it was trying to form an exception message somewhere to report the problem, and something is either returning an encoded string from the __unicode__ method or is throwing the exception in __unicode__. A full strack trace might help debug it - or some messing around with similar queries in an interactive shell or pdb.
1

The UnicodeDecodeError could be a really hard headache. Could be a lot of reasons.

You could try with some of this:


If you are using MySQL as database, you could use a command line like this to create it:

CREATE DATABASE `mydb` CHARACTER SET utf8 COLLATE utf8_general_ci;

See more here.


When you create the Nivel object with the nombre value 'Octavo de Básica', you could try something like this:

nivel_obj = Nivel(
    nombre=unicode('Octavo de Básica', 'utf-8'),
    ...
)

Read more here.


You could also try the encode Python function. here a tutorial

2 Comments

Thanks for your links man. I can't accept it cause I'm using PSQL.
Be sure you are creating a database with utf-8 compatibility.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.