2011-04-18 12 views
18

Co chciałbym zrobić, to aby wyświetlić pojedynczy formularz, który umożliwia użytkownikowi:Jak dodać pole klucza obcego do ModelForm w Django?

  • Wprowadź tytuł dokumentu (z Document modelu)
  • Wybierz jeden z ich user_defined_code wybór z listy rozwijanej (zaludniony przez UserDefinedCode model)
  • wpisać unique_code (przechowywanej w modelu Code)

nie jestem pewien, jak się do tego zabrać wyświetlania pól na pierwszy plan ign kluczowych relacji w formularzu. Wiem, że w widoku można użyć document.code_set (na przykład), aby uzyskać dostęp do powiązanych obiektów dla bieżącego obiektu document, ale nie jestem pewien, jak zastosować to do ModelForm.

Mój model:

class UserDefinedCode(models.Model): 
    name = models.CharField(max_length=8) 
    owner = models.ForeignKey(User) 

class Code(models.Model): 
    user_defined_code = models.ForeignKey(UserDefinedCode) 
    unique_code = models.CharField(max_length=15) 

class Document(models.Model): 
    title = models.CharField(blank=True, null=True, max_length=200) 
    code = models.ForeignKey(Code) 
    active = models.BooleanField(default=True) 

My ModelForm

class DocumentForm(ModelForm): 
    class Meta: 
     model = Document 

Odpowiedz

27

W odniesieniu do wyświetlania pole klucza obcego w postaci można użyć forms.ModelChoiceField i przekazać mu queryset.

tak, forms.py:

class DocumentForm(forms.ModelForm): 
    class Meta: 
     model = Document 

    def __init__(self, *args, **kwargs): 
     user = kwargs.pop('user','') 
     super(DocumentForm, self).__init__(*args, **kwargs) 
     self.fields['user_defined_code']=forms.ModelChoiceField(queryset=UserDefinedCode.objects.filter(owner=user)) 

views.py:

def someview(request): 
    if request.method=='post': 
     form=DocumentForm(request.POST, user=request.user) 
     if form.is_valid(): 
      selected_user_defined_code = form.cleaned_data.get('user_defined_code') 
      #do stuff here 
    else: 
     form=DocumentForm(user=request.user) 

    context = { 'form':form, } 

    return render_to_response('sometemplate.html', context, 
     context_instance=RequestContext(request)) 

z pytaniem:

wiem w widoku można użyć document.code_set (na przykład) do uzyskują dostęp do powiązanych obiektów dla bieżącego obiektu dokumentu , ale ja 'm nie upewnij się, jak zastosować to do ModelForm.

Właściwie twoje Document obiekty nie miałoby .code_set ponieważ relacja FK jest zdefiniowany w modelu dokumentów. Definiuje wiele do jednego związku z Code, co oznacza, że ​​może istnieć wiele obiektów Document na obiekt Code, a nie odwrotnie. Twoje obiekty Code będą miały .document_set. To, co możesz zrobić z obiektu dokumentu, to dostęp, który jest Code związany z używaniem document.code.

edytuj: edit: Myślę, że to zrobi to, czego szukasz. (Niesprawdzone)

forms.py:

class DocumentForm(forms.ModelForm): 
    class Meta: 
     model = Document 
     exclude = ('code',) 

    def __init__(self, *args, **kwargs): 
     user = kwargs.pop('user','') 
     super(DocumentForm, self).__init__(*args, **kwargs) 
     self.fields['user_defined_code']=forms.ModelChoiceField(queryset=UserDefinedCode.objects.filter(owner=user)) 
     self.fields['unique_code']=forms.CharField(max_length=15) 

views.py:

def someview(request): 
    if request.method=='post': 
     form=DocumentForm(request.POST, user=request.user) 
     if form.is_valid(): 
      uniquecode = form.cleaned_data.get('unique_code') 
      user_defined_code = form.cleaned_data.get('user_defined_code') 
      doc_code = Code(user_defined_code=user_defined_code, code=uniquecode) 
      doc_code.save() 
      doc = form.save(commit=False) 
      doc.code = doc_code 
      doc.save() 
      return HttpResponse('success') 
    else: 
     form=DocumentForm(user=request.user) 

    context = { 'form':form, } 

    return render_to_response('sometemplate.html', context, 
     context_instance=RequestContext(request)) 

faktycznie prawdopodobnie chcesz użyć get_or_create podczas tworzenia kodu wynikowego zamiast tego.

doc_code = Code(user_defined_code=user_defined_code, code=uniquecode) 
+0

Dzięki za pomoc.Przeczytałem dokumenty dla ModelChoiceField i teraz ma to sens. Czy wiesz, jak wyświetlić CharField (trzeci punktor w moim pytaniu) dla pola 'unique_code'? Zmniejszyłem trochę moje modele, aby ułatwić ich czytanie, ale zasadniczo mam dokument, któremu przypisano generowany komputerowo, unikalny kod dokumentu. Każdy użytkownik może utworzyć oddzielny kod użytkownika, który jest dołączony jako przedrostek do kodu dokumentu dla wszystkich dokumentów, które posiada, stąd powód wielu modeli. –

+0

@Ben S Okay pozwól mi rzucić okiem. Będę edytować mój post. – DTing

+0

To zadziałało świetnie. Dzięki za pomoc. –

Powiązane problemy