我在__init __()中使用CreateView获得了意外的关键字参数'instance'

时间:2018-08-23 10:59:16

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

我正在使用Django 2.1版本。 我正在尝试制作CreateView。这是我的views.py;

# views.py
class CreateJob(CreateView):
    form_class = CreateJob
    template_name = 'category_list.html'

这是我的forms.py;

# forms.py
from django import forms
from myapp.models import Category

class CreateJob(forms.Form):
    CATEGORY_CHOICES = (
    )
    category_list = forms.ChoiceField(
        widget=forms.Select(attrs={
            "id": "cate"
        }),
        choices=CATEGORY_CHOICES,
        required=True,
    )

    def __init__(self, *args, **kwargs):
        super(CreateJob, self).__init__(*args, **kwargs)
        category_choices = [(cat.id, cat.name) for cat in Category.objects.all()]
        self.fields['category_list'].choices = category_choices

在此forms.py中,我试图创建choicefield和列出类别对象。在我的模板中,当我选择类别时,它将发出ajax请求并列出与类别模型相关的描述列表。您可以在下面查看我的模板。一旦我在forms.py中选择了通过choicefield创建的类别之一,它将在选项中列出具有“ desc” ID的描述列表。

{% extends '../base.html' %}

{% block body %}
   <form action="." method="post">
   {% csrf_token %}
   {{ form }}
   </form>

  <select id="desc">
    {% for description in description_list %}
      <option value="{{ description.pk }}">{{ description.name }}></option>
    {% endfor %}
  </select>
{% endblock %}

{% block script %}
  <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
  <script>
    $(document).ready(function (e) {
      $("#cate").change(function(e) {
        cat = $(this).val();
        var job = $("#desc");
        $.ajax({
          url: 'item/' + cat + '/',
          type: "GET",
          processData: false,
                contentType: false,
                success: function (data) {
                  console.log(data.description_list),
                  job.html(data)
                },
                error: function (xhr, errmsg, err) {
                    console.log(xhr, errmsg, err);
                } // end error: function
            });
        });
    });
  </script>
{% endblock %}

我的urls.py看起来像这样;

path('test/', CreateJob.as_view()),

当我继续进行127.0.0.1:8000/test时,它给了我这个错误:

File "C:\Users\kenan\Desktop\Django\jobs\myapp\forms.py", line 16, in __init__
super(CreateJob, self).__init__(*args, **kwargs)
TypeError: __init__() got an unexpected keyword argument 'instance'
[23/Aug/2018 14:37:03] "GET /test/ HTTP/1.1" 500 89443
  

我想指出的是,我进行了搜索,有人通过将Forms.Form更改为Forms.ModelForm来解决问题。但这不是我想要的。预先感谢!

2 个答案:

答案 0 :(得分:1)

您正在使用CreateView,但是与之关联的表单不是ModelFormModelForm带有一个可选的instance arg(用于编辑现有模型实例)-对于非模型表单来说这不是有效的参数-并且CreateView将此参数传递给表单类实例化时。因此,错误。

TL; DR:如果要使用CreateView,则必须使用ModelForm(或将完全相同 API公开为ModelForm的东西)。< / p>

答案 1 :(得分:0)

如果您只是要使用自定义表单而不是模型表单,并且通常构造字段['category_list']的选择,则无需指定CategoryChoices()或字段。 在 init 中,您可以调用super()然后说

protected void SaveButton_Click(object sender, EventArgs e)
{
    try
    {
        var repo = new DataRepository<Client, ApplicationDbContext>();

        var selectedCategory = GetDropDownListSelection<Category>(CategoryList);
        var selectedSubcategory = GetDropDownListSelection<Category>(SubcategoryList);
        var name = NameTextBox.Text;

        var client = new Client
        {
            Name = name,
            // either
            Category = new DataRepository<Category , ApplicationDbContext>().GetSingleItem(selectedCategory.id),
            // or, easier (assuming you have FK properties defined on the model)
            CategoryId = selectedCategory.Id,
            // repeat as needed
            Subcategory = selectedSubcategory
        };

        repo.AddItem(client);
    }
    // Error handling things
}

或者您可以只创建一个modelchoicefield并声明如下字段:

self.fields['category_list'] = forms.ChoiceField(
            choices=[(cat.id, cat.name) for cat in Category.objects.all()],
            required=False,
            )