0

I want to get a derived modelclass instance from an instanciated base modelclass.

I have the following model class hierarchy:

class AlfrescoPFCModel(models.Model):
    #some fields and methods
    class Meta:
        abstract = True


class Contenido(AlfrescoPFCModel):
    #some fields and methods

class Proyecto(Contenido):
    #some fields and methods

class ProyectoCalificado(Proyecto):
    #some fields and methods

class ProyectoArchivado(ProyectoCalificado):
    #some fields and methods

And I instantiate a Proyecto class in this way:

proyecto = proyecto_form.save(commit=False)
#do some stuff with some fields that dont appear on the form
proyecto.save

In another view I try to access the derived class ProyectoCalificado from the base class Proyecto previously instanciated and saved in the database doing:

pc = ProyectoCalificado.objects.get(pk=id)

and i get: ProyectoCalificado matching query does not exist.

I also tried:

p = get_object_or_404(Proyecto, id=id)
pc = p.proyectocalificado

but it get the same error in the second line.

Reading the documentation i should be allowed to do that: #multi-table-inheritance

What i want to do is to incrementally complete the data associated to a Proyecto (project) following this workflow: Proyecto -> ProyectoCalificado -> ProyectoArchivado. I have 3 different forms for each step. I need 3 different models because I need to save them in the database without filling all the mandatory fields at once.

Thanks!

2 Answers 2

1

Use Form Wizards (https://docs.djangoproject.com/en/dev/ref/contrib/formtools/form-wizard/).

UPDATE

If you can't use Form Wizards because of the situation you describe, then you should make the models fields blank or nullable at the database level and then only enforce field requirements on each individual form. Creating three levels of inheritance solely for the purpose of the single-time set of forms required to create it is absolutely the wrong approach. It only fragments your data across additional tables and makes querying more complicated with no long-term benefit.

So, for example. Set the model itself up as though nothing (or only the items in the first form) are required. Then, in your first form, only make the fields necessary for that particular stage required. You can do this easily by overriding the __init__:

class FirstForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(FirstForm, self).__init__(*args, **kwargs)

        self.fields['some_required_field'].required = True
        # rinse and repeat

Do the same in your second and third forms, again making on the actual fields that are required for that particular form, required.

Then, call it day and have a drink.

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

1 Comment

Thanks, but cant use them because the forms are submited in diferents days by different persons.
0

If you have the child instance, it should have a <base class name>_ptr member which points to the instance of its superclass. You can use this as the basis of a filter query to retrieve the child.

You can also just assume that instances of the base and derived class will have the same id if you haven't done anything to affect how ids are allocated.

1 Comment

thanks! I have the base instance, not the child one and I assume that, but the query pc = ProyectoCalificado.objects.get(pk=id) (being id the id of the base class) doesn´t get anything

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.