动态填充选择字段并获取发布数据中的未选字段

时间:2018-02-19 06:38:18

标签: python django

我有一个表单,我试图比较从数据库中随机选择的两个对象(Cards)。在我的表单中,我尝试使用两张卡动态填充一个选择字段,并在视图中尝试使用用户的选择创建一个对象(CardComparison(winning_card,losing_card))。

我已覆盖表单的__init__以动态填充卡片选项,并且工作正常。问题是,当用户选择卡时,它只会通过所选的卡,而我无法确定视图中未选择哪张卡。

我是Django的新手,我已经意识到我越是挣扎于此,动态选择领域可能不是我真正想要使用的,所以建议更好的方法也是非常感谢。

forms.py:

def get_new_comparison():

    left_card = #get a random card (code hidden for cleanliness)
    right_card = #get a second random card
    left_card_choice = (left_card, left_card.name)
    right_card_choice = (right_card, right_card.name)

    return [left_card_choice, right_card_choice]

class CompareCardsForm(forms.Form):

  def __init__(self, *args, **kwargs):
    post_flag = False
    if kwargs.get('post_flag'):
        post_flag = kwargs.pop('post_flag')

    super(CompareCardsForm, self).__init__(*args, **kwargs)

    if post_flag and len(args) > 0:
        card_name = args[0].get('cards_to_compare')
        card_obj = Card.objects.get(name=card_name)
        card_choice = [(card_obj,card_name)]
        self.fields['cards_to_compare'] = 
             forms.ChoiceField(choices=card_choice, widget=forms.RadioSelect()) 
             #Because everytime the __init__ is called the choices are randomized, I need to set the choices to the POST data's choices otherwise the selected card may not be in the form when it's trying form.is_valid()
    else:
        self.fields['cards_to_compare'] = forms.ChoiceField(choices=get_new_comparison(), widget=forms.RadioSelect())

views.py:

def CompareCards(request):
if request.method == 'POST':
    form = CompareCardsForm(request.POST, post_flag=True)
    if form.is_valid():
        print(form.cleaned_data['cards_to_compare'])
        # Here is where I want to create a new comparison using the two cards
        return HttpResponseRedirect(reverse('comparecards'))
    else:
        print(form.errors.as_text())

else:
    form = CompareCardsForm()

return render(
    request,
    'mtg_compare/comparecard.html', 
    {'form': form}
)

1 个答案:

答案 0 :(得分:0)

实际上,通过使用模板文件解决了这个问题。通过在模板文件中添加隐藏字段并将选项设置为表单中的可访问变量,您可以提取字段并将其添加到POST消息中,以便我可以在视图中访问它们。

comparecard.html:

{% extends "base_generic.html" %}
{% block content %}

<h1>Compare Cards</h1>
<h2>Choose a card to win the matchup</h2>
<p>
<p>

<form action="" method="post">
    {% csrf_token %}
    <table>
        {{ form.cards_to_compare }}
    </table>
    <input type="hidden" value="{{ form.card_list }}" name="var_name_1" /> 
    <input type="submit" value="Submit" />

</form>
{% endblock %}

forms.py:

class CompareCardsForm(forms.Form):

def get_fresh_comparison():
    return get_new_comparison()

def __init__(self, *args, **kwargs):
    post_flag = False
    if kwargs.get('post_flag'):
        post_flag = kwargs.pop('post_flag')

    super(CompareCardsForm, self).__init__(*args, **kwargs)

    if post_flag and len(args) > 0:
        card_name = args[0].get('cards_to_compare')
        card_obj = Card.objects.get(name=card_name)
        card_choice = [(card_obj,card_name)]
        self.card_list = card_choice
        self.fields['cards_to_compare'] = forms.ChoiceField(choices=card_choice, widget=forms.RadioSelect())

    else:
        self.card_list = get_new_comparison()
        self.fields['cards_to_compare'] = forms.ChoiceField(choices=self.card_list, widget=forms.RadioSelect())

views.py:

def CompareCards(request):
if request.method == 'POST':
    form = CompareCardsForm(request.POST, post_flag=True)
    if form.is_valid():
        print(request.POST.get('var_name_1'))
        return HttpResponseRedirect(reverse('comparecards'))
    else:
        print(form.errors.as_text())