ModelChoiceField invalid literal for int() with base 10: ''

醉酒当歌 提交于 2019-12-24 20:29:31

问题


So I've spent the day trying to chase down a custom thing that I wanted to achieve using FormView. When I use FormView with HTML form method="POST", I am able to get the desired result, mostly.

If a user clicks to submit a form and an empty field exists, they get an error message telling them the form is required. I'm aware that I can make the ModelChoiceField required on the form, but was trying to implement my own logic for this.

I found through my searching that if I'm not updating anything via the form, form method="GET" may be more appropriate. So I switched to that, and basically got this method working, but my error logic still doesn't quite work the way I'd expect.

Long story short, I can use the form method="GET", but when I try to do validation on the form, it doesn't work. Worse yet, if I try to include an empty label, that creates an invalid literal message, because based on this SO...In a Django template, how to specify a dictionary key which is itself an attribute? It doesn't seem possible to specify error logic/validation if the first field is essentially empty, which it is in order to create a blank first choice on ModelChoiceField.

Here's my code...

The Form...

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 = ''

The HTML...

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

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

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

The Views...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

DetailView....

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

Model...

Essentially just User...with a One to One with UserProfile...

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

Essentially, if I removed the empty_label line from my form, the form validates, provided that the queryset isn't empty. If I include the empty_label line of code and the user clicks on the submit button without selecting anything, they get an invalid literal for int() with base 10: '' message. It seems the only way to work around this is to make the ModelChoiceField required=True, with the empty_label reference.

Using the request.GET appears to behave differently than the POST for good reason, I'm aware. When I used the POST instead, everything works exactly as I want it to, except there doesn't appear to be a way to prevent the error message that I'm using to show up if the user clicks on the BACK button.

I explored some Javascript solutions today that were recommeneded via this SO, How To Clear self.add_error in Django if user clicks on browser back button? but to no avail.

Has anyone else encountered this struggle? Based on my knowledge up until this point, in this case since I'm not updating the records in question and just displaying them, form method="GET" would seem to make the most sense, but I seem to be pretty limited as to my options on how I can keep a blank first position in my ModelChoiceField and also do any kind of my own validation on the field in question without encountered the invalid literal message.

Thanks in advance for any thoughts.


回答1:


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

Um, I'm a little baffled myself, but this doesn't look right, the two return statements. Try something like above. Also:

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



回答2:


Leveraging this SO....How to prevent submitting the HTML form's input field value if it empty I was able to determine that the best way to go about this was to add the following Javascript to by my code...

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

The code above forces a 404 instead of the invalid literal message that I was getting before.



来源:https://stackoverflow.com/questions/57155919/modelchoicefield-invalid-literal-for-int-with-base-10

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!