Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Putting a number for school creates an invalid profile state #3746

Closed
willgearty opened this issue Mar 29, 2024 · 3 comments · Fixed by #3748
Closed

Putting a number for school creates an invalid profile state #3746

willgearty opened this issue Mar 29, 2024 · 3 comments · Fixed by #3748

Comments

@willgearty
Copy link
Member

If a student enters a number for the K12 school field, the profile form will submit fine. However, upon trying to submit the profile form again, it will then error with the following message:

K12School matching query does not exist.

My guess is that the form validation guesses that these numeric values correspond to a K12 School object, rather than just a string and then attempts to look up the object (but finds none).

@willgearty
Copy link
Member Author

It's possible this is a broader issue related to AjaxForeignKeyNewformField:

class AjaxForeignKeyNewformField(forms.IntegerField):

@willgearty
Copy link
Member Author

Indeed, it looks like the clean function takes this to be an object ID:

try:
id = int(value)
except ValueError:
match = get_id_re.match(value)
if match:
id = int(match.groups()[0])
else:
# Reverted to standard behavior because some forms need their
# AjaxForeignKey fields to be required. -Michael P 8/31/2009
if self.required:
raise forms.ValidationError('This field is required.')
else:
id = None

I think the easiest fix here might be to change the front end functionality so that when a number is manually entered, we make it clear that this isn't an autocomplete value:

javascript = """
<script type="text/javascript">
<!--
$j(function () {
$j("#id_%(fn)s").val("%(init_val)s");
$j("#id_%(fn)s_data").val("%(data)s");
$j("#id_%(fn)s").autocomplete({
source: function(request, response) {
$j.ajax({
url: "/admin/ajax_autocomplete/",
dataType: "json",
data: {
model_module: "%(model_module)s",
model_name: "%(model_name)s",
ajax_func: "%(ajax_func)s",
ajax_data: request.term,
prog: "%(prog)s",
},
success: function(data) {
var output = $j.map(data.result, function(item) {
return {
label: item.ajax_str,
value: item.ajax_str,
id: item.id
};
});
response(output);
}
});
},
select: function(event, ui) {
$j("#id_%(fn)s_data").val(ui.item.id);
%(shadow_field_javascript)s
},
change: function(event, ui) {
$j("#id_%(fn)s_data").val(ui.item ? ui.item.id : null);
$j("#id_%(shadow_field)s").val($j("#id_%(fn)s").val());
}
});
});

Another option (probably easier) is to require that manual values are not only numbers (via regex maybe).

@willgearty
Copy link
Member Author

Actually, I think an even easier change would be to use filter() and exists() here:

if id:
return self.field.rel.to.objects.get(id=id)

If the object with that ID doesn't exist, then we should just return None (or raise an error if a proper value is required).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant