2013-05-09 19 views
1

我已經看到很多類似的帖子,但沒有足夠的信息來幫助我。是否可以在初始提交模型表單時使用Django內聯表單?

聲明:我是非常新的Django。

我正在嘗試爲我的公司創建一個就業應用程序,該應用程序將託管在子域(例如jobs.mycompany.com)上 - 這是我第一個真正的Django項目。以及我希望爲最終用戶完成的事情已經在管理部分完成了。

基本上,我打破了工作申請成幾個部分:

  • 申請人(只能有這些之一)
  • 教育(的教育記錄[即一所學校 - 可多
  • Job_Experience(組織申請人曾在 - 可以是多個
  • 可用性( 像漢蘭達,只能有一個

這裏的問題 - 我不認爲我正確地把這個變成一種形式,我也沒有一個知道如何保存所有的這些在一次。我有企圖EducationJob_Experience製作表單集,但我認爲我沒有正確應用這些。基本上,我希望所有這些都出現,當用戶點擊「提交」時,它會創建所有必要的記錄 - 申請人和可用性是實際需要的唯一部分。

編輯

再次重申:管理面板是做正是我想要實現對前端的東西。,但(在前端),我一直未能:

  • applicant選擇輸入去,走
  • 分配applicant實例非申請人車型
  • 我可能是錯的,但我認爲可能有辦法將這些表單統一爲一個實例,而不是像現在這樣將多個實例傳遞給視圖。下面

代碼:

models.py

from django.db import models 
from django import forms 
from django.forms import ModelForm 
from datetime import datetime 

class Applicant(models.Model): 
    name = models.CharField(max_length=200) 
    city = models.CharField(max_length=200) 
    state = models.CharField(max_length=200) 
    zip = models.CharField(max_length=200) 
    social_security_number = models.CharField(max_length=200) 
    phone = models.CharField(max_length=200) 
    alt_phone = models.CharField(max_length=200, blank=True) 
    us_citizen = models.BooleanField() 
    committed_felony = models.BooleanField() 
    is_16 = models.BooleanField() 
    has_drivers_license = models.BooleanField() 
    is_disabled = models.BooleanField() 
    prev_employed = models.BooleanField() 
    felony_explanation = models.TextField(blank=True) 
    disabled_explanation = models.TextField(blank=True) 
    prev_employment_manager = models.CharField(max_length=200, blank=True) 
    prev_employment_year = models.CharField(max_length=4, blank=True) 
    skills = models.TextField() 

    def __unicode__(self): 
     return self.name 

class Education(models.Model): 
    GED = 'GED' 
    HIGH_SCHOOL = 'HIG' 
    JUNIOR_COLLEGE = 'JUN' 
    UNIVERSITY = 'UNI' 
    TYPE_OF_SCHOOL_CHOICES = (
     (GED, 'GED'), 
     (HIGH_SCHOOL, 'High School'), 
     (JUNIOR_COLLEGE, 'Junior College'), 
     (UNIVERSITY, 'University'), 
    ) 

    type = models.CharField(
     max_length=3, 
     choices=TYPE_OF_SCHOOL_CHOICES, 
     default=HIGH_SCHOOL 
    ) 
    school_name = models.CharField(max_length=200) 
    school_city = models.CharField(max_length=200) 
    school_state = models.CharField(max_length=200) 
    graduated = models.BooleanField() 
    graduation_year = models.CharField(max_length=4) 
    applicant = models.ForeignKey(Applicant) 

class Job_Experience(models.Model): 
    FULL_TIME = 'F' 
    PART_TIME = 'P' 
    FTPT_CHOICES = (
     (FULL_TIME, 'Full Time'), 
     (PART_TIME, 'Part Time'), 
    ) 

    organization_name = models.CharField(max_length=200) 
    organization_city = models.CharField(max_length=200) 
    organization_state = models.CharField(max_length=200) 
    supervisor_name = models.CharField(max_length=200) 
    supervisor_phone = models.CharField(max_length=200) 
    supervisor_contact_allowed = models.BooleanField() 
    currently_employed = models.BooleanField() 
    start_date = models.DateField() 
    end_date = models.DateField() 
    starting_title = models.CharField(max_length=200) 
    ending_title = models.CharField(max_length=200) 
    start_salary = models.CharField(max_length=20) 
    end_salary = models.CharField(max_length=20) 
    reason_for_leaving = models.TextField() 
    full_time_part_time = models.CharField(
     max_length = 1, 
     choices = FTPT_CHOICES, 
     default = PART_TIME 
    ) 
    applicant = models.ForeignKey(Applicant) 

class Availability (models.Model): 
    NOT_AVAILABLE = 'XX' 
    OPEN_AVAILABILITY = 'OP' 
    AVAILABLE_BETWEEN = 'AB' 
    AVAILABILITY_CHOICES = (
     (NOT_AVAILABLE, 'Not Available'), 
     (OPEN_AVAILABILITY, 'Available All Day'), 
     (AVAILABLE_BETWEEN, 'Available Between Certain Hours'), 
    ) 

    mon_availability = models.CharField(
     max_length = 2, 
     choices = AVAILABILITY_CHOICES, 
     default = NOT_AVAILABLE 
    ) 
    mon_hours_start = models.CharField(max_length = 10) 
    mon_hours_end = models.CharField(max_length = 10) 
    tue_availability = models.CharField(
     max_length = 2, 
     choices = AVAILABILITY_CHOICES, 
     default = NOT_AVAILABLE 
    ) 
    tue_hours_start = models.CharField(max_length = 10) 
    tue_hours_end = models.CharField(max_length = 10) 
    wed_availability = models.CharField(
     max_length = 2, 
     choices = AVAILABILITY_CHOICES, 
     default = NOT_AVAILABLE 
    ) 
    wed_hours_start = models.CharField(max_length = 10) 
    wed_hours_end = models.CharField(max_length = 10) 
    thu_availability = models.CharField(
     max_length = 2, 
     choices = AVAILABILITY_CHOICES, 
     default = NOT_AVAILABLE 
    ) 
    thu_hours_start = models.CharField(max_length = 10) 
    thu_hours_end = models.CharField(max_length = 10) 
    fri_availability = models.CharField(
     max_length = 2, 
     choices = AVAILABILITY_CHOICES, 
     default = NOT_AVAILABLE 
    ) 
    fri_hours_start = models.CharField(max_length = 10) 
    fri_hours_end = models.CharField(max_length = 10) 
    fri_availability = models.CharField(
     max_length = 2, 
     choices = AVAILABILITY_CHOICES, 
     default = NOT_AVAILABLE 
    ) 
    sat_hours_start = models.CharField(max_length = 10) 
    sat_hours_end = models.CharField(max_length = 10) 
    sat_availability = models.CharField(
     max_length = 2, 
     choices = AVAILABILITY_CHOICES, 
     default = NOT_AVAILABLE 
    ) 
    sun_hours_start = models.CharField(max_length = 10) 
    sun_hours_end = models.CharField(max_length = 10) 
    applicant = models.OneToOneField(Applicant) 

# Forms 

class ApplicantForm(ModelForm): 
    class Meta: 
     model = Applicant 

class EducationForm(ModelForm): 
    class Meta: 
     model = Education 

class JobExperienceForm(ModelForm): 
    class Meta: 
     model = Job_Experience 

class AvailabilityForm(ModelForm): 
    class Meta: 
     model = Availability 

views.py

from django.shortcuts import render 
from django.http import HttpResponse 
from django.template import Context, loader 
from applications.models import Applicant, Education, Job_Experience, Availability, ApplicantForm, EducationForm, JobExperienceForm, AvailabilityForm 
from django.forms.formsets import formset_factory 


def index(request): 
    education_formset = formset_factory(EducationForm, extra=3) 
    message = 'Forms have not been submitted.' 

    if request.method == 'POST': 
     applicant_form = ApplicantForm(request.POST) 
     education_form = education_formset(request.POST) 
     if applicant_form.is_valid() and education_form.is_valid(): 
      applicant_form.save() 
      education_form.applicant = applicant_form 
      message = 'Forms are valid.' 
     else: 
      message = 'Forms are not valid.' 
    else: 
     applicant_form = ApplicantForm() 
     education_form = education_formset() 

    return render(request, 
     'applications/index.html', 
     { 
      'applicant_form' : applicant_form, 
      'education_form' : education_form, 
      'message' : message 
     } 
    ) 

管理。PY

from django.contrib import admin 
from applications.models import Applicant, Education, Job_Experience, Availability 

class EducationInline(admin.StackedInline): 
    model = Education 
    extra = 3 

class JobExperienceInline(admin.StackedInline): 
    model = Job_Experience 
    extra = 3 

class AvailabilityInline(admin.StackedInline): 
    model = Availability 

class ApplicantAdmin(admin.ModelAdmin): 
    inlines = [EducationInline, JobExperienceInline, AvailabilityInline] 

admin.site.register(Applicant, ApplicantAdmin) 

的index.html

<h1>Employment Application</h1> 
<p>Please enter your information into the fields below.</p> 
<hr /> 
<p>{{ message }}</p> 
<hr /> 
<form action="{% url 'applications:index' %}" method="post"> 
    {% csrf_token %} 
    {{ applicant_form.as_p }} 
    <hr /> 
    {{ education_form.as_p }} 
    <input type="submit" /> 
</form> 
+0

對帖子標題問題的回答是'是';但我確定這不是你所希望的。請使用您嘗試的相關代碼重新編輯/編輯您的問題,並縮小範圍。請參閱['FAQ'](http://stackoverflow.com/faq)。 – 2013-05-09 05:46:43

+0

@BurhanKhalid查看我的編輯 - 是否更清楚? – drewwyatt 2013-05-09 05:56:22

回答

1

我意識到這是一個幾個月的時間,也許你已經使用Django解決了這個問題,或者現在正在使用其他的東西,但是你非常接近。爲您的使用情況基本視圖模式是:

  1. 設置該formset
  2. 驗證父窗體
  3. 驗證表單集

類似以下內容:

def index(request): 

    EducationFormSet = formset_factory(
     Application, 
     Education, 
     form=EducationForm, 
     extra=3, 
    ) 

    if request.method == 'POST': 
     application_form = ApplicationForm(request.POST) 

     if application_form.is_valid(): 
      application = application_form.save(commit=False) 
      education_formset = EducationFormSet(request.POST, instance=application) 

      if education_formset.is_valid(): 
       application.save() 
       education_formset.save() 

       return HttpResponseRedirect(reverse('thanks_and_good_luck_view')) 
     else: 
      education_formset = EducationFormSet(request.POST) 
    else: 
     application_form = ApplicationForm() 
     education_formset = EducationFormSet() 

    return render_to_response(
     'applications/index.html', 
     { 
      'application_form': application_form, 
      'education_formset': education_formset, 
     }, 
     context_instance=RequestContext(request) 
    ) 

這裏棘手的一點是commit=False保存父窗體時。這允許您獲取父級模型的未提交實例,以用於formset中的子模型實例。

+0

我最終以另一種方式解決了這個問題,之後又轉向主要使用Rails,但是,我很欣賞SOMEONE最終達成這一目標。 – drewwyatt 2013-08-23 00:32:23

0

當我明白你的問題,你想在前端相同的管理內嵌的功能。

django admin應用程序在其前端使用自定義的jquery。其中一部分是自動生成子表單。

要開始您自己的前端,請從文檔中的formsets部分開始。這將爲您提供關於多個子表單在視圖中的工作原理。然後你可以移動到inline formsets這是管理員用來呈現其形式。

對於javascript部分,您可以使用或其他更全面的東西,如crispy forms,它可以爲dynamic inlines提供更好的呈現和支持。

+0

以下是我現在正在使用的牆:https://docs.djangoproject.com/en/dev/topics/forms/modelforms/#inline-formsets 此示例中的內聯窗體集預計以前存在的Author實例 - 使用Django的例子 - 我怎麼能指定一個新的作者,以及他所有的書籍? – drewwyatt 2013-05-09 15:17:54

相關問題