2015-01-28 4 views
0

Я пытаюсь использовать вместе autocomplete_light и django-dynamic-formset: обе работают одни, но я не могу позволить им работать вместе ... давайте начнем с код ...autocomplete_light и django-dynamic-formset не работают вместе

models.py:

class Tmp_User(models.Model): 
    userName = models.CharField(max_length=200, blank=True, null=True,) 
    firstName = models.CharField(max_length=200, blank=True, null=True,) 
    lastName = models.CharField(max_length=200, blank=True, null=True,) 
    ... 
class Project(models.Model): 
    title = models.CharField() 
    ... 
class Segment_in_Project(models.Model): 
    name = models.CharField() 
    the_project = models.ForeignKey('Project') 
    translator = models.ForeignKey('Tmp_User') 
    ... 

forms.py

autocomplete_light.autodiscover() 

class AddProjectForm(forms.ModelForm): 
    def __init__(self, *args, **kwargs): 
     super(AddProjectForm, self).__init__(*args, **kwargs) 
    class Meta: 
     model = Project 
     fields = '__all__' 

class AddSegmentForm(autocomplete_light.ModelForm): 
    def __init__(self, *args, **kwargs): 
     super(AddSegmentForm, self).__init__(*args, **kwargs) 
    class Meta: 
     model = Segment_in_Project 
     autocomplete_exclude = ['the_project'] 
     fields = '__all__' 

SegmentFormSet = formset_factory(AddSegmentForm) 

autocomplete_light_registry.py

autocomplete_light.register(Tmp_User, 
    search_fields=['^firstName', 'lastName']) 

и views.py

class ProjectCreateView(CreateView): 
    model = Project 
    template_name = 'home/formset-table.html' 
    form_class = AddProjectForm 
    success_url = '/admin' 

    def get(self, request, *args, **kwargs): 
     self.object = None 
     form_class = self.get_form_class() 
     form = self.get_form(form_class) 
     formset = SegmentFormSet() 
     return self.render_to_response(
      self.get_context_data(
       form_Project=form,   
       formset_Segment=formset)) 

    def post(self, request, *args, **kwargs): 
     self.object = None 
     form_class = self.get_form_class() 
     form = self.get_form(form_class) 
     formset = SegmentFormSet(self.request.POST) 
     if (form.is_valid() and formset.is_valid()): 
      return self.form_valid(form, formset) 
     else: 
      return self.form_invalid(form, formset) 

    def form_valid(self, form, formset): 
     self.object = form.save() 
     self.object.save() 
     formset.instance = self.object 
     formset.save() 
     return super(ProjectCreateView, self).form_valid(form) 

    def form_invalid(self, form, formset): 
     return self.render_to_response(
      self.get_context_data(
       form_Project=form, formset_Segment=formset)) 

Проблема заключается в том, что formset экземпляр не «привязан» к модели проекта и проверкам не в состоянии: ошибка говорит, что the_project не определена ... Я пытался сначала сохранить форму, получить идентификатор нового сохраненного проекта и передать его в набор форм вместе с запросом. POST, когда я объявляю набор форм ... но он не работал ...

с другой стороны вручную, используя inlineformset_factory(Project,Segment_in_Project) вместо formset_factory, разрывает функциональность autocomplete_light ... (я не знаю, как используйте autocomplete_light.ModelForm для набора форм Segment_in_Project)

Любая идея или предложения о том, как это сделать? Thanks

ответ

0

OK. После небольшого пробного дня я нашел решение. Это не идеально в том смысле, что он делает то, что мне нужно, но у меня все еще есть ощущение, что должно быть что-то лучше ...

Во всяком случае, что я сделал, это полностью взломать функцию post: сначала я сохраняю ProjectModel, то я получаю идентификатор сохраненного проекта, затем я читаю информацию POST-формы (которая не имеет никакой информации об идентификаторе только что созданного проекта), получите необходимую мне информацию и создайте новый набор форм с соответствующим проектом ID, а затем я сохраню его. Код ниже:

def post(self, request, *args, **kwargs): 
    self.object = None 
    form_class = self.get_form_class() 
    form = self.get_form(form_class) 
    form.instance.created_by = self.request.user 
    formset = SegmentFormSet(self.request.POST) 
    if form.is_valid(): 
     self.object = form.save() 
    newdata = {} 
    for idx, form in enumerate(formset): 
     for field in form.fields: 
      print idx, field, form[field].value() 
      if field == 'the_project': 
       tmp_field = u"form-%s-the_project"%(idx) 
       newdata[tmp_field] = self.object.id 
      elif field == 'id': 
       pass 
      else: 
       tmp_field = u"form-%s-%s"%(idx,field) 
       newdata[tmp_field] = form[field].value() 
    newdata[u"form-MAX_NUM_FORMS"] = u"1000" 
    newdata[u"form-MIN_NUM_FORMS"] = u"0" 
    newdata[u"form-INITIAL_FORMS"] = u"0" 
    newdata[u"form-TOTAL_FORMS"] = len(formset) 
    newdata[u"title"] = self.object.title 
    new_formset = SegmentFormSet(newdata) 
    if new_formset.is_valid(): 
     return self.form_valid(form, new_formset) 
    else: 
     return self.form_invalid(form, new_formset) 

Как вы видите, NewData ДИКТ именно то, что мне нужно (в том числе проекта ID) для правильного сохранения SegmentFormSet.

Если у кого-то есть лучшее решение ... пожалуйста, дайте мне знать

 Смежные вопросы

  • Нет связанных вопросов^_^