0

次のモデルがあります:Topic、UserProfile、UserSubscribeToTopic

これらの最後は次のようになります。

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 テーブルで LEFT JOIN を実行します。raw に頼らずに Django でこれを行う方法がわかりません。

私の質問:

  • 左結合から生成されたフォームセットにクエリセットを指定することはできないと思いますか?
  • ModelForm をあきらめて、手動で入力するフォームセットを使用する方がよいでしょうか?
  • より良いアプローチはありますか?!
4

2 に答える 2

0

チェックボックスを日付フィールドから分離することになったので、 Form で 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()
于 2012-05-08T14:57:41.067 に答える
0

Topicモデルにフォームを作成し、user_setマネージャーを使用して、現在のユーザーがトピックを購読しているかどうかを確認する必要があります。

フォームが送信されると、いずれかのフィールドがチェックされている場合UserSubscribedToTopic、ビューで個々のオブジェクトを作成できます。

于 2012-04-27T12:48:56.437 に答える