Редактировать форму в django - PullRequest
0 голосов
/ 13 апреля 2020

В моем приложении django я пытаюсь понять отношения многих ко многим, и я использую набор форм для хранения таких данных:

Views.py

def Team_Form(request):

   if request.POST:
        form = TeamForm(request.POST)
        form.player_instances = PlayerFormset(request.POST)
        if form.is_valid():
            team= Team()
            team.tname= form.cleaned_data['tname']
            team.save()

        if form.player_instances.cleaned_data is not None:
            for item in form.player_instances.cleaned_data:
                player = Player()
                player.pname= item['pname']
                player.hscore= item['hscore']
                player.age= item['age']
                player.save()
                team.player.add(player)
            team.save()

   else:
        form = TeamForm()
        return render(request, 'packsapp/employee/new.html', {'form':form})

Модели. py

class Player(models.Model):
    pname = models.CharField(max_length=50)
    hscore = models.IntegerField()
    age = models.IntegerField()
    def __str__(self):
       return self.pname

class Team(models.Model):
    tname = models.CharField(max_length=100)
    player= models.ManyToManyField(Player)
    def __str__(self):
        return self.tname

Forms.py

class PlayerForm(forms.Form):
    pname = forms.CharField()
    hscore= forms.IntegerField()
    age = forms.IntegerField()

PlayerFormset= formset_factory(PlayerForm)

class TeamForm(forms.Form):
   tname= forms.CharField()
   player= PlayerFormset()

HTML

<html>
<head>

    <title>gffdfdf</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
    <script src="/static/jquery.formset.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>

</head>
<body>

<div class="container">

    <form id="myForm" action="" method="post" class="">
        {% csrf_token %}
        <h2> Team</h2>
        {% for field in form %}
        {{ field.errors }}
        {{ field.label_tag }}  {{ field }}
        {% endfor %}
        {{ form.player.management_form }}

        <h3> Product Instance(s)</h3>
        <table id="table-product" class="table">
            <thead>
            <tr>
                <th>player name</th>
                <th>highest score</th>
                <th>age</th>
            </tr>

            </thead>
            {% for player in form.player %}
            <tbody class="player-instances">

            <tr>
                <td>{{ player.pname }}</td>
                <td>{{ player.hscore }}</td>
                <td>{{ player.age }}</td>
                <td><input id="input_add" type="button" name="add" value=" Add More "
                           class="tr_clone_add btn data_input"></td>

            </tr>

            </tbody>
            {% endfor %}
        </table>
        <button type="submit" class="btn btn-primary">save</button>

    </form>
</div>

<script>
    var i = 1;
    $("#input_add").click(function () {
        $("tbody tr:first").clone().find(".data_input").each(function () {
            if ($(this).attr('class') == 'tr_clone_add btn data_input') {
                $(this).attr({
                    'id': function (_, id) {
                        return "remove_button"
                    },
                    'name': function (_, name) {
                        return "name_remove" + i
                    },
                    'value': 'Remove'
                }).on("click", function () {
                    var a = $(this).parent();
                    var b = a.parent();
                    i = i - 1
                    $('#id_form-TOTAL_FORMS').val(i);
                    b.remove();

                    $('.player-instances tr').each(function (index, value) {
                        $(this).find('.data_input').each(function () {
                            $(this).attr({
                                'id': function (_, id) {
                                    console.log("id", id)
                                    var idData = id;
                                    var splitV = String(idData).split('-');
                                    var fData = splitV[0];
                                    var tData = splitV[2];
                                    return fData + "-" + index + "-" + tData
                                },
                                'name': function (_, name) {
                                    console.log("name", name)
                                    var nameData = name;
                                    var splitV = String(nameData).split('-');
                                    var fData = splitV[0];
                                    var tData = splitV[2];
                                    return fData + "-" + index + "-" + tData
                                }
                            });
                        })
                    })
                })
            } else {
                $(this).attr({
                    'id': function (_, id) {
                        console.log("id", id)

                        var idData = id;
                        var splitV = String(idData).split('-');
                        var fData = splitV[0];
                        var tData = splitV[2];
                        return fData + "-" + i + "-" + tData
                    },
                    'name': function (_, name) {
                        console.log("name", name)

                        var nameData = name;
                        var splitV = String(nameData).split('-');
                        var fData = splitV[0];
                        var tData = splitV[2];
                        return fData + "-" + i + "-" + tData
                    }
                });

            }
        }).end().appendTo("tbody");
        $('#id_form-TOTAL_FORMS').val(1 + i);
        $("tbody tr:last :input").each(function () {
            $(this).attr({
                'id': function (_, id) {
                    return id.replace(/\d/g, i)
                },
                'name': function (_, name) {
                    return name.replace(/\d/g, i)
                },
            })
        })

        i++;

    });
</script>

</body>
</html>

Что мне не удалось понять, так это то, как редактировать набор форм, который я только что сохранил или, чтобы лучше сформулировать вопрос, как передать сохраненный экземпляр в набор форм для его редактирования?

Обновление :

Я попробовал modelformset_factory, и он выбирает все объекты от Player в посте, а также обновление

Forms.py

PlayerFormset= modelformset_factory(Player, fields=('pname','hscore','age'))

Снимок экрана:

При попытке отредактировать команду Matt:

enter image description here

Ответы [ 3 ]

1 голос
/ 13 апреля 2020

Здесь «многие ко многим» означает, что один игрок может входить в несколько команд, а также что в одной команде может быть много игроков.

Чтобы решить вашу проблему, вы должны создать другой вид (ссылка на ту же форму ), который покажет вашу форму, но уже заполнить. В вашей функции pk для вашей команды.

def updateTeam(request,pk):

  team = Team.objects.get(id=pk)
  form = TeamForm(instance=team)


if request.method == "POST":
    form = TeamForm(request.POST, instance=team)
    if form.is_valid():
        form.save()

context = {'form': form}
return render(request, 'accounts/order_form.html', context)

Это должно решить вашу проблему!

Не стесняйтесь, если у вас есть какие-либо вопросы

0 голосов
/ 20 апреля 2020

Дополнительно к ответу { ссылка } от Матье-ОД

вы можете изменить

PlayerFormset= formset_factory(PlayerForm)

на

modelformset_factory

https://docs.djangoproject.com/en/3.0/ref/forms/models/#django .forms.models.modelformset_factory

, и в методе init команды TeamForm вы должны иметь возможность настроить набор запросов для набора формы модели, чтобы показывать только игроков этой команды.

если вы не настроите его, будет показан каждый игрок

РЕДАКТИРОВАТЬ:

Я бы также предложил использовать формы моделей, поскольку ваши формы предназначены для моделей: https://docs.djangoproject.com/en/3.0/topics/forms/modelforms/#modelform

я также нашел этот вопрос, который кажется похожим: Django ModelForm для полей «многие ко многим»

0 голосов
/ 15 апреля 2020

Если вы этого хотите, то вам необходимо передать заполненную форму обратно в шаблон. Хорошим примером этого в документах является https://docs.djangoproject.com/en/3.0/topics/forms/formsets/#using -a-formset-in-views-and-templates . В вашем коде это будет выглядеть так (не пробовал с шаблоном):

def team_view(request):
    PlayerFormset = formset_factory(PlayerForm)

    if request.POST:
        form = TeamForm(request.POST)
        form.player_instances = PlayerFormset(request.POST)
        if form.is_valid():
            team = Team()
            team.tname = form.cleaned_data['tname']
            team.save()

            if form.player_instances.cleaned_data is not None:
                for item in form.player_instances.cleaned_data:
                    player = Player()
                    player.pname= item['pname']
                    player.hscore= item['hscore']
                    player.age= item['age']
                    player.save()
                    team.player.add(player)
                team.save()

        else:
            form = TeamForm()
        return render(request, 'packsapp/employee/new.html', {'form': form})

Я изменил пару вещей. Прежде всего, используйте строчные буквы для представлений на основе функций и старайтесь не использовать имя «форма» в представлении. Кроме того, обратите внимание на отступ: у 'if form.player_instances.cleaned_data ...' есть дополнительный отступ. Не стоит использовать проверку игроков, если нет команды, вы не сможете спасти (несуществующую) команду. Затем: оператор return теперь находится на том же уровне, что и первый оператор if / else. В вашей версии нет возврата после сохранения формы. При этом заполненная форма (из части if оператора) возвращается в контекстную переменную. Тогда шаблон должен решить, что с ним делать. В другом случае возвращается пустая форма.

Я заметил, что этот проект, по-видимому, учебное пособие, по StackOverflow есть как минимум два связанных вопроса: Django Dynami c Форма для многих отношений и Как сохранить django динамические c данные набора форм, используя формы и представления . Может быть, вы можете учиться у них.

...