【问题标题】:ModelChoiceField invalid literal for int() with base 10: ''基数为 10 的 int() 的 ModelChoiceField 无效文字:''
【发布时间】:2019-12-01 00:19:55
【问题描述】:

所以我花了一天的时间来尝试实现一个我想使用 FormView 实现的自定义功能。当我使用带有 HTML 表单方法 =“POST”的 FormView 时,大部分情况下我能够获得所需的结果。

如果用户单击提交表单并且存在空字段,他们会收到一条错误消息,告诉他们该表单是必需的。我知道我可以在表单上制作所需的 ModelChoiceField,但正在尝试为此实现我自己的逻辑。

我通过搜索发现,如果我不通过表单更新任何内容,form method="GET" 可能更合适。所以我切换到那个,基本上让这个方法工作了,但是我的错误逻辑仍然不能像我期望的那样工作。

长话短说,我可以使用表单方法="GET",但是当我尝试对表单进行验证时,它不起作用。更糟糕的是,如果我尝试包含一个空标签,则会创建一个无效的文字消息,因为基于此 SO...In a Django template, how to specify a dictionary key which is itself an attribute? 如果第一个字段基本上是空的,似乎无法指定错误逻辑/验证,这是为了在 ModelChoiceField 上创建一个空白的首选。

这是我的代码...

形式...

dropdown = forms.ModelChoiceField(queryset=Author.objects.filter(is_active=True),required=False)

def __init__(self, *args, **kwargs):
    # q = kwargs.pop('dropdown', None)
    dropdown = kwargs.pop('dropdown', None)
    super(AuthorByNameForm, self).__init__(*args, **kwargs)
    self.fields['dropdown'].empty_label = ''

HTML...

<form method="GET" action="{% url 'Main:author_detail' %}">

  <h1 class="class">View By Author</h1>

  <div>
    {{ form.dropdown }}
  </div>

意见...FORMVIEW

class AuthorByNameView(LoginRequiredMixin,FormView):
    form_class = AuthorNameForm
    template_name = 'author_by_name.html'

 def get_form_kwargs(self):
     kwargs = super(AuthorByNameView, self).get_form_kwargs()
     kwargs['dropdown'] = self.request.GET.get("dropdown")
     return kwargs

详细视图....

class AuthorDetailView(LoginRequiredMixin,DetailView):
    model = Author
    template_name = 'author_detail.html'

def get_object(self, queryset=None):
    return get_object_or_404(Author, id=self.request.GET.get("dropdown"))
    return get_object_or_404

型号...

基本上只是用户...与 UserProfile 一对一...

class UserProfile(models.Model):
    user = models.OneToOneField(User,on_delete=models.CASCADE)

基本上,如果我从表单中删除了 empty_label 行,只要查询集不为空,表单就会验证。如果我包含 empty_label 代码行并且用户在未选择任何内容的情况下单击提交按钮,他们会得到一个无效的 int() 文字,基数为 10: '' 消息。似乎解决此问题的唯一方法是使用 empty_label 引用使 ModelChoiceField required=True。

我知道,使用 request.GET 的行为似乎与 POST 不同,这是有充分理由的。当我改用 POST 时,一切都完全按照我的意愿工作,除了似乎没有办法阻止我用来在用户单击“返回”按钮时显示的错误消息。

我今天探索了一些通过这个 SO 推荐的 Javascript 解决方案, How To Clear self.add_error in Django if user clicks on browser back button? 但无济于事。

还有其他人遇到过这种斗争吗?根据我到目前为止的知识,在这种情况下,由于我没有更新有问题的记录而只是显示它们,所以 form method="GET" 似乎是最有意义的,但我似乎非常有限关于如何在 ModelChoiceField 中保留空白的第一个位置以及如何在相关字段上进行任何类型的验证而不遇到无效文字消息的选项。

提前感谢您的任何想法。

【问题讨论】:

  • 发布模式和视图
  • @Jay 感谢您的回复。如果您有任何其他问题,请告诉我。

标签: javascript html django django-forms django-views


【解决方案1】:
def get_object(self, queryset=None):
    foo = get_object_or_404(Author, id=self.request.GET.get("dropdown"))
    return foo

嗯,我自己有点困惑,但这看起来不对,两个返回语句。尝试类似上面的东西。另外:

  self.fields['dropdown'].empty_label = None

【讨论】:

  • 感谢您的建议。我改变了 get_object 但它没有任何区别。我还更改了 empty_label 参考...这就是问题所在。我想要一个空标签...表单开头有一个空格...如果我将空标签包含为“”,这就是导致问题的原因...当用户单击提交和他们没有选择任何东西。您的空标签参考基本上解决了我对非空查询集的问题......但如果是,我想在用户单击空字段上的提交时进行验证。继续获取无效的文字。
  • 所以你只是想让表单工作而不在前端显示标签。如“姓名:[输入字段],密码[输入字段]:[输入字段]??您希望第三个标签为空白,我理解正确吗?
  • 不确定我们是否在同一页面上。我有一个带有一个下拉字段的表单。在一个完美的世界里,我想让表单加载一个空白标签。然后,如果用户单击提交表单并且没有选择任何内容,我希望能够验证它并向视图发送错误消息。在这种情况下,使用 GET,似乎没有办法验证表单,并且在用户单击提交并且它是空白后,它立即进入无效文字错误。如果我做 POST,我实际上会验证下拉列表。
  • 似乎带有空标签 = '' 的 GET 和 ModelChoiceField 似乎并没有放在一起。
  • 所以,假设您使用带有标签“密码”而不是模型选择字段的密码输入字段,在这种情况下,您会希望输入框在没有单词“密码”的情况下加载和处理在它面前??对吗?
【解决方案2】:

利用这个 SO....How to prevent submitting the HTML form's input field value if it empty 我能够确定解决此问题的最佳方法是通过我的代码添加以下 Javascript...

$('form').submit(function() {
  var dropdown = $('#id_dropdown').val();
  if (dropdown === undefined || dropdown === "") {
    $('#id_dropdown').attr('name', '' );
  } else {
    $('#id_dropdown').attr('name', 'dropdown');
  }
});
  });

上面的代码强制执行 404,而不是我之前收到的无效文字消息。

【讨论】:

    猜你喜欢
    • 2013-05-31
    • 2018-03-13
    • 1970-01-01
    • 2021-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-06
    相关资源
    最近更新 更多