Ошибка: «Выберите правильный выбор. Этот выбор не является одним из доступных при попытке отправить ModelForm - PullRequest
2 голосов
/ 13 января 2020

Я получаю ошибку 'Выберите правильный выбор. Этот выбор не является одним из доступных при попытке отправить ModelForm. Хотя значения, передаваемые из внешнего интерфейса, выглядят корректными (PK для каждого) и все необходимые значения предоставляются, но он все равно не возвращает мне очищенных данных

Я все еще новичок в Django и поиск в Google не дал мне результатов, которые работают

(также я использую хрустящие формы для оформления внешнего интерфейса)

forms.py


    code = forms.CharField(required=True)
    itemtype = forms.ModelChoiceField(required=True, queryset=ItemType.objects.all())
    location = forms.ModelChoiceField(required=True, queryset=Location.objects.all())
    parent = forms.ModelChoiceField(required=False, queryset=Item.objects.all())

    class Meta:
        model = Item
        fields = ['code', 'itemtype', 'location', 'parent']

    def __init__(self, *args, **kwargs):

            super(CreateItemWithParentForm, self).__init__(*args, **kwargs)
            for field in self.fields:
                self.fields[field].widget.attrs = {'class': 'form-control'}

            self.fields['itemtype'].label_from_instance = lambda obj: "{0}".format(obj.name)
            self.fields['location'].label_from_instance = lambda obj: "{0}".format(obj.address)
            self.fields['parent'].label_from_instance = lambda obj: "{0}".format(obj.code)

            self.helper = FormHelper(self)
            self.helper.form_show_labels = True
            self.helper.form_id = 'createitemform'

            self.helper.layout = Layout(
                Fieldset("Create New Item",
                         Field('code', css_class="mt-2", placeholder="Code", name="code", id="code"),
                         Field('itemtype', css_class="mt-2", name="itemtype", placeholder="Item type", css_id="itemtype"),
                         Field('location', css_class="mt-2", name="location", placeholder="Location", css_id="location"),
                         Field('parent', css_class="mt-2", name="parent", placeholder="Parent Item", css_id="parent"),
                         Button('createitemformbutton', 'Submit', css_class="btn-light"),
                         css_class='border',
                    )
            )

views.py

class CreateItemWithParent(FormView):
    """
    create a new item with specified parent
    """
    template_name = 'add_item.html'
    form_class = CreateItemWithParentForm
    success_url = reverse_lazy('add_item_success')

    def get_initial(self):
            return {"pk": self.kwargs.get('pk')}

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        ...
        return context

    def clean_itemtype(self):
        data = self.cleaned_data['itemtype']
        return data

    def clean_location(self):
        data = self.cleaned_data['location']
        return data

    def clean_parent(self):
        data = self.cleaned_data['parent']
        return data

    def form_valid(self, form):

        return super().form_valid(form)


def save_new_item_with_parent(request):

    options = {}

    if request.method == 'POST':
        item_form = CreateItemWithParentForm(request.POST)

        if item_form.is_valid():

            child = _add_item(item_form.cleaned_data['code'], int(item_form.cleaned_data['itemtype']), int(item_form.cleaned_data['location']))

            parent = item_form.cleaned_data['parent']['id']

            if child != -1:
                if parent != "-1":
                    if _add_itemitem(int(parent), int(child)):
                        options['success'] = True
                    else:
                        options['success'] = False
                else:
                    options['success'] = True
            else:
                options['success'] = False            
        else:
            print('form not valid')
            print(item_form.errors)

    return JsonResponse(options)

    class Meta:
        model = Item
        fields = ['code', 'itemtype', 'location', 'parent']

    def __init__(self, *args, **kwargs):

            super(CreateItemWithParentForm, self).__init__(*args, **kwargs)
            for field in self.fields:
                self.fields[field].widget.attrs = {'class': 'form-control'}

            self.fields['itemtype'].label_from_instance = lambda obj: "{0}".format(obj.name)
            self.fields['location'].label_from_instance = lambda obj: "{0}".format(obj.address)
            self.fields['parent'].label_from_instance = lambda obj: "{0}".format(obj.code)

            self.helper = FormHelper(self)
            self.helper.form_show_labels = True
            self.helper.form_id = 'createitemform'

            self.helper.layout = Layout(
                Fieldset("Create New Item",
                         Field('code', css_class="mt-2", placeholder="Code", name="code", id="code"),
                         Field('itemtype', css_class="mt-2", name="itemtype", placeholder="Item type", css_id="itemtype"),
                         Field('location', css_class="mt-2", name="location", placeholder="Location", css_id="location"),
                         Field('parent', css_class="mt-2", name="parent", placeholder="Parent Item", css_id="parent"),
                         Button('createitemformbutton', 'Submit', css_class="btn-light"),
                         css_class='border',
                         )
            )

models.py

class ItemType(models.Model):
    name = models.TextField(default='')
    start = models.DateTimeField(null=True)
    description = models.TextField(default='')
    history = HistoricalRecords()

    def __str__(self):
        return self.id

class Location(models.Model):
    name = models.TextField(default='')
    address = models.TextField(default='')
    history = HistoricalRecords()

    def __str__(self):
        return self.id

class Item(models.Model):
    ITEMTYPE_CHOICES = ItemType.objects.values('id', 'name')
    LOCATION_CHOICES = Location.objects.values('id', 'address')
    # children = models.ManyToManyField('Item', through='ItemItem')
    code = models.TextField(default='')
    itemtype = models.ForeignKey('ItemType', on_delete=DO_NOTHING, choices=ITEMTYPE_CHOICES)
    location = models.ForeignKey('Location', on_delete=DO_NOTHING, choices=ITEMTYPE_CHOICES)
    created = models.DateTimeField(null=True, auto_now=True)
    edited = models.DateTimeField(null=True, auto_now=True)
    history = HistoricalRecords() 

HTML шаблон (с Jquery)

<section class="container-fluid" id="home">
    <section class="container-fluid" id="intro_text">
        <h2>Add Item</h2>
        <div class="row">
            <div id="mainpane" class="col-md-12">
                <div class="dd" id="success"></div>
                {% csrf_token %}
                {% crispy form %}
            </div>
        </div>
    </section>
</section>

<script type="text/javascript">
$(document).ready(function(){
    $("#button-id-createitemformbutton").on("click", function(){
        $.ajax({
            url : "{% url "save_new_item_with_parent" %}",
            type : "POST",
            data: $("#createitemform").serialize(),
            dataType: 'json',
            success: function(result) {
                if(result.success){
                    $("#success").html('Your item has been recorded in the database. <a href="/item/list/">View all items?</a>');
                    $("#success").removeClass('dd');

                    // reset form
                    $("#code").val('');
                    $("#id_itemtype").val(1);
                    $("#id_location").val(1);
                    if(window.location.pathname.length < 11){
                        $("#id_parent").val(-1);
                    }

                }
                if(!result.success){
                    alert(result.errors);
                }
            },
        });
    });

});
</script>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...