2012-04-26 42 views
0

FORMSET我有以下型号:主题,用户配置,UserSubscribedToTopic填充一个Django使用左连接

最后,这些看起来是这样的:

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) 

我几乎得到我想要的东西,如果我添加以下我的看法:

但是,显然,这将只显示用户已订阅的主题。为了显示我真正需要做的所有主题,请在主题表格中加入一个LEFT JOIN。我看不到如何在Django中做到这一点,而不诉诸生。

我的问题:

  • 我是否正确的思维,不可能指定一个查询集为 是从左连接生成的表单集?
  • 放弃ModelForm并使用我手动填充的formset会更好吗?
  • 有没有更好的方法?

回答

0

我最终从日期字段中分离出复选框,所以我可以在表单中使用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 '' 

查看:

GET:

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) 

POST:

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() 
0

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

提交表单后,如果检查了任何字段,则可以在视图中创建单独的对象UserSubscribedToTopic