使用左联接填充Django表单集
我有以下模型:Topic、UserProfile、UserSubscribedToTopic 最后一个看起来像这样:使用左联接填充Django表单集,django,formset,Django,Formset,我有以下模型:Topic、UserProfile、UserSubscribedToTopic 最后一个看起来像这样: class UserSubscribedToTopic(models.Model): topic = models.ForeignKey(Topic) user_profile = models.ForeignKey(UserProfile) start_date = models.DateField(null=True, blank=True) 我想向
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()))
然而,很明显,这只会显示用户已经订阅的主题。要显示我真正需要做的所有主题,只需在Topic表上进行左连接。我看不出在Django如何做到这一点,而不诉诸原始材料
我的问题是:
我是否认为不可能为指定查询集
从左联接生成的表单集?
这样会更好吗
放弃ModelForm并使用我手动填充的表单集?
还有更好的方法吗?!
您应该在主题模型上创建表单,然后使用用户集管理器查看当前用户是否已订阅该主题
提交表单后,如果选中了任何字段,则可以在视图中创建单个UserSubscribedToTopic对象。最后,我将复选框与日期字段分开,以便在表单中使用forms.ModelMultipleChiiceField和手动创建的表单集来处理日期字段 代码如下: 表格:
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()