ModelForms em Django onde o modelo subjacente depende de um outro modelo (via OneToOneField)

votos
4

Eu tenho dois modelos na minha aplicação Django, para fins de armazenamento de parâmetros de busca utilizados para alguns programas de pesquisa de homologia:

# models.py
class Search(models.Model):
    A class to represent search runs.

    program = models.CharField(max_length=20)
    results_file = models.FileField(
        upload_to=(SEARCH_RESULTS_DIR)
    )
    timestamp = models.DateTimeField()

    def __unicode__(self):
        return u'%s %s' % (self.program, self.timestamp)


class FastaRun(models.Model):

    search = models.OneToOneField('Search', primary_key=True)
    # the user-input FASTA formatted protein sequence
    query_seq = models.TextField()
    # -b Number of sequence scores to be shown on output.
    number_sequences = models.PositiveIntegerField(blank=True)
    # -E Limit the number of scores and alignments shown based on the
    # expected number of scores. Overrides the expectation value.
    highest_e_value = models.FloatField(default=10.0,
            blank=True)
    # -F Limit the number of scores and alignments shown based on the
    # expected number of scores. Sets the highest E-value shown.
    lowest_e_value = models.FloatField(blank=True)
    mfoptions = [
            ('P250', 'PAM250'),
            ('P120', 'PAM120'),
            ('BL50', 'BLOSUM50'),
            ('BL62', 'BLOSUM62'),
            ('BL80', 'BLOSUM80')
    ]
    matrix_file = models.CharField(
            max_length=4,
            choices=mfoptions,
            default='BL50'
    )
    database_option = models.CharField(
            max_length=25,
            choices=BLAST_DBS,
            default=INITIAL_DB_CHOICE
    )
    ktupoptions = [(1, 1), (2, 2)]
    ktup = models.PositiveIntegerField(
            choices=ktupoptions,
            default=2,
            blank=True
    )

Note aqui que FastaRuné uma espécie de Search. FastaRunestende-se pesquisar em que há mais parâmetros definidos para um FastaRun. Um FastaRundeve ter uma Searchinstância à qual está vinculado, e este Searchexemplo é a chave primária da FastaRun.

Eu tenho um ModelFormpara a FastaRunclasse.

# views.py
class FastaForm(forms.ModelForm):

    class Meta:
        model = models.FastaRun

Eu tenho uma função ponto de vista que eu preciso usar para preencher um FastaForme salvar uma nova Searchinstância e uma nova FastaRuninstância com base no formulário enviado pelo usuário. A forma que não incluem a opção de escolher um Searchexemplo. Isso é impossível de fazer, porque o Searchexemplo só pode existir uma vez que o usuário realmente submete nesta pesquisa.

Abaixo está um esboço do que a função precisa fazer:

# also in views.py
def fasta(request, ...):
    # populate a FastaForm from the information POSTed by the user--but
    # how to do this when there's no Search information coming in from
    # the user's request. We need to create that Search instance, too,
    # but we also have to...

    # validate the FastaForm
    # ... before we can ...

    # create a Search instance and save() it

    # use this saved Search instance and give it to the FastaForm [how?]

    # save() the FastaForm [save the world]

    pass

Porque o Searche FastaRun(e portanto FastaForm) estão interligados, eu sinto como se estivesse entrando em um Catch-22. Eu preciso para salvar um Searchexemplo, cujos parâmetros são armazenados na solicitação POST, mas cujos parâmetros devem ser validados usando o FastaForm'validação s. No entanto, acho que o FastaFormnão pode ser instanciado até que eu tenha instanciado um Searchexemplo. No entanto, não posso instanciar uma Searchinstância até que eu tenha validar usando o FastaForm... Você começa a idéia.

O que estou perdendo aqui? Deve haver uma maneira bastante limpa para fazer isso, mas me falta a clareza para vê-lo.

Além disso, me corrija se eu estiver errado, mas esta mesma situação de dependência pode ocorrer a qualquer momento que você tem algum tipo de relação entre os modelos (por exemplo, também para ForeignKeye ManyToManycampos). Assim, alguém certamente descobriram isso.

Publicado 06/05/2009 em 20:50
fonte usuário
Em outras línguas...                            


1 respostas

votos
2

Este é um caso onde eu iria usar a herança para cuidar do presente:

# models.py
class Search(models.Model):
    """A class to represent search runs."""
    ...

class FastaRun(Search):
    # one-to-one field has been removed
    ....

Agora, instanciar um FastaRuné, por definição, também instanciar um Search. Django lida com o lado do banco de dados de isso corretamente, também, através da criação de uma tabela separada para FastaRuncom uma chave para Search. Sua validação deve funcionar como esperado com o formulário. A única coisa que você pode querer adicionar se você estiver indo para fazer qualquer pergunta sobre o Searchobjeto seria adicionar um campo de tipo para Searchque é o substituído por todas as subclasses, assim você pode filtrar esses resultados.

Respondeu 07/05/2009 em 23:27
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more