mardi 14 juin 2016

django adding field to a model "error list index out of range" when migrating

I created a model to integrate a multiple images field, which was perfectly integrated with my current showroom plugin.

Then I added 2 text field to the model (the ones in the translations), but this time when I'm trying to migrate I have this awesome explicit error:

File "/var/www/webapps/lib/python3.4/site-packages/django/db/backends/postgresql_psycopg2/introspection.py", line 149, in get_constraints
"foreign_key": tuple(used_cols[0].split(".", 1)) if kind.lower() == "foreign key" else None,
IndexError: list index out of range

I know how to "solve" this error but it would mean deleting my DB field referring to this plugin. Which I don't want as in production I have a lot already fill and I don't want to recreate all the profiles.

So, here is the class with the 2 new fields:

class ProfilePartnerExamples(ModelMeta, TranslatableModel):
    profilepartner = models.ForeignKey(ProfilePartner, related_name='example_partner_profile')
    examples = FilerImageField(verbose_name=_('Example images'), blank=True,
                              null=True,
                              on_delete=models.SET_NULL,
                              help_text=_('The example images for partner profile'))

    translations = TranslatedFields(
        project_title=models.CharField(_('Project name'), max_length=255),
        slug=models.SlugField(_('slug'), blank=False, db_index=True, max_length=150),
        description_image=HTMLField(_('image description'), default='', blank=True,
                          configuration='HTMLFIELD_CKEDITOR_SETTINGS_CONTENT'),
    )

    _metadata = {
        'examples': 'get_image_full_url',
    }

    def get_image_full_url(self):
        if self.examples:
            return self.examples.url
        return ''

    def save(self, *args, **kwargs):
        super(ProfilePartnerExamples, self).save(*args, **kwargs)
        main_lang = self.get_current_language()
        for lang in self.get_available_languages():
            self.set_current_language(lang)
        self.set_current_language(main_lang)
        self.save_translations()

    def get_slug(self):
        return self.safe_translation_getter(
            'slug',
            language_code=get_language(),
            any_language=False)

    def get_absolute_url(self, current_app=None):
        """
        Warning: Due to the use of django application instance namespace
        (for handle multi instance of an application)we add the possibility
        to use it with the reverse.
        So if get_absolute_url is call without app instance it may failed (
        for example in django_admin)
        """
        lang = get_language()
        if self.has_translation(lang):
            kwargs = {'slug': self.get_slug()}
            return reverse('djangocms_partner_profile:project-detail',
                           kwargs=kwargs,
                           current_app=current_app)
        return reverse('djangocms_partner_profile:project-list', current_app=current_app)

    def get_full_url(self, site_id=None):
        return self._make_full_url(self.get_absolute_url(), site_id)

    def _make_full_url(self, url, site_id=None):
        if site_id is None:
            site = Site.objects.get_current()
        else:
            site = Site.objects.get(pk=site_id)

        return get_full_url(url, site)

    def __str__(self):
        project_title = self.safe_translation_getter('project_title', any_language=True)
        return project_title if project_title is not None else '(not translated)'

Why does it fail?

I can't do it with migrate zero blabla, losing my data in prod would be terrible.

Aucun commentaire:

Enregistrer un commentaire