Django: não ModelMultipleChoiceField não selecionar opções iniciais

votos
25

não ModelMultipleChoiceField não selecionar opções iniciais e eu não posso fazer o trabalho seguinte correção (link abaixo) no meu exemplo:

http://code.djangoproject.com/ticket/5247#comment:6

Meus modelos e forma:

class Company(models.Model):
    company_name = models.CharField(max_length=200)

class Contact(models.Model):
    company = models.ForeignKey(Company)
    first_name = models.CharField(max_length=100)
    last_name = models.CharField(max_length=100)

class Action(models.Model):
    company = models.ForeignKey(Company, blank=True, null=True)
    from_company = models.ManyToManyField(Contact, verbose_name='Participant(s) from Company', blank=True, null=True)

class Action_Form(ModelForm):
    from_company = forms.ModelMultipleChoiceField(queryset=Contact.objects.none(), widget=forms.CheckboxSelectMultiple())
    class Meta:
        model = Action

O que eu faço e os resultados:

>>> contacts_from_company = Contact.objects.filter (company__exact = 1) # 1 para o teste, caso contrário, uma variável
>>> form = Action_Form (inicial = { 'from_company': [o.pk para o em contacts_from_company]}) # como sugerido na correção
>>> forma de impressão [ 'from_company']
<Ul>
</ Ul>
>>> print contacts_from_company
[<Contact: teste de pessoa>, <Contact: uma outra pessoa>]

>>> form2 = Action_Form (inicial = { 'from_company': contacts_from_company})
>>> form2 impressão [ 'from_company']
<Ul>
</ Ul>

>>> Forma3 = Action_Form (inicial = { 'from_company': Contact.objects.all ()})
>>> Form3 print [ 'from_company']
<Ul>
</ Ul>

A maneira que eu estava esperando que ele iria trabalhar:
1. Minha visão fica empresa de request.GET
2. Em seguida, filtra todos os contatos para que empresa
3. Finalmente, ele cria um formulário e passa esses contactos como = iniciais {...}

Duas perguntas:
1. [não respondeu ainda] Como posso fazer ModelMultipleChoiceField tomar esses valores iniciais?
2. [respondido] Como alternativa, eu posso passar uma variável para Action_Form (ModelForm) para que na minha ModelForm eu poderia ter:

from_company = forms.ModelMultipleChoiceField (queryset = Contact.objects.filter (company__exact = some_id) # onde some_id vem a partir de uma vista
Publicado 28/01/2009 em 16:30
fonte usuário
Em outras línguas...                            


4 respostas

votos
21

Eu estou respondendo por 1)

1. Como posso fazer ModelMultipleChoiceField tomar esses valores "iniciais"?

Isso pode ser feito em seu Action_Form __init__método usando ModelMultipleChoiceField initialatributo.

Como diz o código fonte Django ( db / modelos / campos / related.py ) em def formfield(self, **kwargs):

        # If initial is passed in, it's a list of related objects, but the
        # MultipleChoiceField takes a list of IDs.

Então, você precisa dar-lhe uma lista de IDs:

class Action_Form(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(Action_Form, self).__init__(*args, **kwargs)
        self.fields['from_company'].initial = [c.pk for c in Contact.object.filter()]
Respondeu 07/10/2009 em 11:01
fonte usuário

votos
14

Você precisará adicionar um __init__método para Action_Formdefinir seus valores iniciais, lembrando-se de chamar __init__na base ModelFormclasse através de super .

class Action_Form(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(Action_Form, self).__init__(*args, **kwargs)
        self.fields['from_company'].queryset = Contact.object.filter(...

Se você pretende passar o filtro params args como palavra-chave para Action_Form, você precisará removê-los antes de super invocação:

myfilter = kwargs['myfilter']
del kwargs['myfilter']

ou, provavelmente melhor:

myfilter = kwargs.pop('myfilter')

Para mais informações, aqui está uma outra ligação do ModelForms dinâmicos em Django .

Respondeu 28/01/2009 em 16:45
fonte usuário

votos
11

Se a resposta anterior não foi simples e direta o suficiente, eu tento responder 1) novamente:

  1. Como posso fazer ModelMultipleChoiceField tomar esses valores "iniciais"?

Você pode deixar Action_Formcomo era na pergunta original, e apenas usar isso para tornar exatamente o que você quer:

>>> form4 = Action_Form(initial={'from_company': Contact.objects.all().values_list('id',flat=True)})
>>> print form4['from_company']
Respondeu 12/10/2010 em 14:13
fonte usuário

votos
10

Resposta a (1) pergunta!

Isso não vai funcionar:

self.fields['from_company'].initial = [c.pk for c in Contact.object.filter()]

Mas isso vai realmente funciona :

self.initial['from_company'] = [c.pk for c in Contact.object.filter()]
Respondeu 18/12/2013 em 16:14
fonte usuário

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