【问题标题】:Can't apply retrieved form data to multiple objects无法将检索到的表单数据应用于多个对象
【发布时间】:2020-10-28 01:38:40
【问题描述】:

我正在尝试使用具有一个字段的表单(在呈现的template.html 中显示为下拉列表)来更改同一模型的多个对象的属性。但是,由于某种原因,我无法将检索到的表单数据应用于对象。

models.py:

class Player(models.Model):
    class Race(models.TextChoices):
        HUMAN = "Human"
        UNDEAD = "Undead"
    race = models.CharField(choices=Race.choices)

forms.py:

class PlayerRaceForm(ModelForm):
    class Meta:
        model = Player
        fields = [
            'race'
        ]

views.py:

def index(request):
    players = Player.objects.all()
    player_race_form = PlayerRaceForm()
    if request.method == 'POST':
        print(player_race_form.errors) # nothing here
        print(player_race_form.non_field_errors) # see next code block
        if player_race_form.is_valid(): # it aint for some reason :/
            for player in players:
                player.race = player_race_form.cleaned_data['race']
                player.save()
    
    context = {'player_race_form': player_race_form,}
    return render(request, 'template.html', context)

开启print(player_race_form.non_field_errors):

<bound method BaseForm.non_field_errors of <PlayerRaceForm bound=False, valid=False, fields=(race)>>

我尝试bypass is_validcleaned_data 并使其以某种方式工作,但它保存了一个明显错误的值,不在 Race 类中。

def index(request):
    players = Player.objects.all()
    player_race_form = PlayerRaceForm()
    if request.method == 'POST':
        print(player_race_form.errors) # nothing here
        print(player_race_form.non_field_errors) # see next code block
        for player in players:
            player.race = player_race_form['race'].value()
            # player.race = player_race_form.data['race'] #MultiValueDictKeyError
            player.save()

    context = {'player_race_form': player_race_form,}
    return render(request, 'template.html', context)

还尝试只修改一个对象:

def index(request):
    players = Player.objects.all()
    player_race_form = PlayerRaceForm()
    if request.method == 'POST':
        print(player_race_form.errors) # nothing here
        print(player_race_form.non_field_errors) # see next code block
        if player_race_form.is_valid(): # it aint for some reason :/
           player[0].race = player_race_form.cleaned_data['race']
           player[0].save()
    
    context = {'player_race_form': player_race_form,}
    return render(request, 'template.html', context)

还是不行。

虽然理论上很容易通过创建一些 if-else 语句来将表单中的值与Race 中的实际值相匹配来破解它,但这样做有点浪费,所以我'想要一个 Django 方法来解决这个问题。

【问题讨论】:

    标签: python python-3.x django django-views django-forms


    【解决方案1】:

    我已经重现了您的错误。然后使用来自 GeeksForGeeks 的关于 forms 的建议 我在几个地方更改了您的代码:

    models.py

    class Player(models.Model):
        class Race(models.TextChoices):
            HUMAN = "Human"
            UNDEAD = "Undead"
        race = models.CharField(max_length=6, choices=Race.choices)  # added max_lenght because of makemigrations error
    

    forms.py

    from django import forms  # imported it and used it below 
    from projects.models import Player
    
    
    class PlayerRaceForm(forms.ModelForm):  # instead of ModelForm
        class Meta:
            model = Player
            fields = "__all__"  # geeks suggestion, but yours work just fine
    

    views.py

    def index(request):
        context = {}
        player_race_form = PlayerRaceForm(request.POST or None, request.FILES or None)
        if player_race_form.is_valid():
            player_race_form.save()
            # print(player_race_form)  # uncomment ii to see valid, saved form
    
        context['form'] = player_race_form
        return render(request, 'projects/template.html', context)
    

    我的 templates.html 也是这样的:

    <form action = "" method = "post">
        {% csrf_token %}
        {{form}}
        <input type="submit" value="Submit">
    </form>
    

    和我在控制台中的输出:

    <tr><th><label for="id_race">Race:</label></th><td><select name="race" required id="id_race">
      <option value="">---------</option>
    
      <option value="Human" selected>Human</option>
    
      <option value="Undead">Undead</option>
    
    </select></td></tr>
    

    我认为,它正确保存了选定的值:)

    【讨论】:

    • 您好!它保存吗?我的问题是由于某种原因它没有保存,我已经可以显示下拉列表了。造成误解,我深表歉意
    猜你喜欢
    • 2019-09-14
    • 2016-07-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-17
    • 2012-12-09
    相关资源
    最近更新 更多