【问题标题】:Populating a Django formset using a left join使用左连接填充 Django 表单集
【发布时间】:2012-04-26 20:28:01
【问题描述】:

我有以下模型:Topic、UserProfile、UserSubscribedToTopic

最后一个看起来像这样:

class UserSubscribedToTopic(models.Model):
    topic = models.ForeignKey(Topic)
    user_profile = models.ForeignKey(UserProfile)
    start_date = models.DateField(null=True, blank=True)

我想向用户显示一个主题列表,每个主题都有一个复选框。如果用户选中一个复选框,那么我将使用 JavaScript 来显示“开始日期”文本字段(因此出于这个问题的目的,我只需要在复选框旁边显示一个文本字段)。如果用户已经保存了他们的选择并正在重新访问页面,我想在表单首次呈现时相应地填充表单。

我尝试使用表单集来做到这一点:

class SubscribeToTopicForm(ModelForm):
class Meta:
    model = UserSubscribedToTopic
    fields = ('topic','start_date')
    widgets = {'topic': CheckboxInput(attrs={'class': 'topic-checkbox'}),
               'start_date': TextInput(attrs={'class': 'date','placeholder': 'Start date'})}

SubscribeToTopicFormSetBase = modelformset_factory(
    UserSubscribedToTopic,
    form=SubscribeToTopicForm,
    extra = 0)

class SubscribeToTopicFormSet(SubscribeToTopicFormSetBase):
def add_fields(self, form, index):
    super(SubscribeToTopicFormSet, self).add_fields(form, index)

如果我将以下内容添加到我的视图中,我几乎得到了我想要的:

topics_formset = SubscribeToTopicFormSet(queryset=UserSubscribedToTopic.objects.filter(user_profile=user.get_profile()))

但是,显然这只会显示用户已经订阅的主题。要显示我真正需要做的所有主题是在主题表上的左连接。如果不使用 raw,我看不到如何在 Django 中执行此操作。

我的问题:

  • 我认为不可能为 从左连接生成的表单集?
  • 会不会更好 放弃 ModelForm 并使用我手动填充的表单集?
  • 有更好的方法吗?!

【问题讨论】:

    标签: django formset


    【解决方案1】:

    您应该在Topic 模型上创建表单,然后使用user_set 管理器查看当前用户是否已订阅该主题。

    提交表单后,如果选中任何字段,您可以在视图中创建单独的 UserSubscribedToTopic 对象。

    【讨论】:

      【解决方案2】:

      我最终将复选框与日期字段分开,因此我可以在表单中使用 forms.ModelMultipleChoiceField 和手动创建的表单集来处理日期字段。

      代码如下:

      表格:

      class SubscribedToTopicForm(ModelForm):
          subscribed_to_topic = forms.ModelMultipleChoiceField(required=False,queryset=Topic.available_topics, widget=forms.CheckboxSelectMultiple(attrs={'class': 'topic-checkbox'}))
          class Meta:
          model = UserProfile
          fields = ("subscribed_to_topic",)
      
          def get_checked_topics(self):
              return self.cleaned_data['subscribed_to_topic']
      
      class StartDateForm(forms.Form):
          topic_id = forms.CharField(widget=forms.HiddenInput,required=False)
          start_date = forms.DateField(required=False,label='')
      
      StartDateFormSetBase = formset_factory(form=StartDateForm,extra = 0)
      
      class StartDateFormSet(StartDateFormSetBase):
          def get_start_date(self, topic_id):
              for i in range(0, self.total_form_count()):
                  form = self.forms[i]
                  form_topic_id=long(form.cleaned_data['topic_id'])
                  if topic_id == form_topic_id:
                      return form.cleaned_data['start_date']
              return ''
      

      查看:

      获取:

      topics_form = SubscribedToTopicForm()
      subscribed_to_topic=None
      if request.user.is_authenticated():
          subscribed_to_topics = SubscribedToTopic.objects.filter(user_profile=request.user.get_profile())
      initial_data = []
      for topic in Topic.available_topics.all():
          start_date=''
          if subscribed_to_topics:
              for subscribed_to_topic in subscribed_to_topics:
                  if subscribed_to_topic.topic.id==topic.id:
                      start_date=subscribed_to_topic.start_date
          initial_data.append({'topic_id':topic.id, 'start_date': start_date})
      start_date_formset = StartDateFormSet(initial=initial_data)
      

      发布:

      start_date_formset = StartDateFormSet(request.POST)
      topics_form = SubscribedToTopicForm(request.POST)
      start_date_formset.is_valid()
      topics_form.is_valid()
      for topic in topics_form.get_checked_topics():
          start_date = start_date_formset.get_start_date(topic.id)
          subscribed_to_topic = SubscribedToTopic()
          subscribed_to_topic.topic=topic
          subscribed_to_topic.start_date=start_date
          subscribed_to_topic.save()
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-05-17
        • 1970-01-01
        • 2022-01-01
        • 1970-01-01
        • 2019-09-10
        • 2018-12-12
        • 2014-10-08
        • 2018-09-06
        相关资源
        最近更新 更多