( I come from stackoverflow in Spanish for help )
I have an interesting problem, first of all the model as such:
class Reserve(models.Model):
client = models.CharField(max_length = 200)
employee_of_turn = models.ForeignKey(User, on_delete = models.CASCADE)
The problem is to create an instance of the Reserve model through the CreateView view, which will create a form to create that instance, but in the form I do not want to display the field employee_of_turn I want only the client field to be shown and that by default the value of the field employee_of_turn is the user who logged in at that time.
Well to solve this problem, try to modify the data sent by the POST method, in the get_form_kwargs method:
class ReserveCreateView(CreateView):
model = Reserve
template_name = 'testapp1/example.html'
fields = ['client']
success_url = reverse_lazy('home')
def get_form_kwargs(self):
form_kwargs = super().get_form_kwargs()
if form_kwargs.get('data'):
user = User.objects.get(username = self.request.user)
post = self.request.POST.copy()
post['employee_of_turn'] = str(user.pk)
form_kwargs['data'] = post
return form_kwargs
The fact is that it does not work, I always get this error:
django.db.utils.IntegrityError: NOT NULL constraint failed: testapp1_reserve.employee_of_turn_id
I started trying to figure out where exactly the error occurred, because the solution of the get_form_kwargs method that I showed earlier, should fix the error, and the error occurs in the form_valid method, specifically in the form.save(), here the source code of the method form_valid:
ModelFormMixin:
def form_valid(self, form): """If the form is valid, save the associated model.""" self.object = form.save() return super().form_valid(form)FormMixin:
def form_valid(self, form): """If the form is valid, redirect to the supplied URL.""" return HttpResponseRedirect(self.get_success_url())
( I did the following with the intention of seeing how the structure of the data is when the instance was created, without omitting fields and when the field employee_of_turn was omitted, in order to replicate the structure at the time of omitting said field and at the time of modify said data, and thus be able to solve the problem, avoiding errors )
Case 1:
In the form_valid method, I printed form.data when in the fields attribute it had the following value:
fields = ['client']
Case 2:
Then I did the same but in this case the fields attribute had the following values:
fields = ['client', 'employee_of_turn']
I printed the data in the form_valid method in the following way, since this was where the error specifically arose and there was a possibility that the data was not sent as I modified it before:
def form_valid(self, form):
print(form.data)
The result of printing it in the 2 cases was as follows:
<QueryDict: {'csrfmiddlewaretoken': ['SBRSJa0aw4iNJOMPwtQVsFL6V6y1cFMNGne9Kr0fA7YmtYeD8xshhDq6pc1mKjQs'], 'client': ['code2'], 'employee_of_turn': ['1']}>
That means that whether you print form.data in Case 1 or Case 2, the data is exactly the same, which means that the problem is not the data at the time of modifying it, it is something else (I deduce).
Since even when printing form.is_valid() in the form_valid method, it results in True.
So why is it wrong, if I am replicating the data structure correctly when modifying it? I don't make sense of this error, the whole modification process I am doing correctly.
Note:
Many think that in reality the field employee_of_turn awaits an object in the form or view, I sent an id and may think that this is the error, but it is not so.
First of all, I tried, instead of putting an id in the field employee_of_turn, I put an object, and gave the same error.
The reason that the field employee_of_turn expects an id and not an object is because this is how the view manages it, at least when receiving the data by the POST method, I don't know why it is managed like this, that's how they decided Django developers.
This can be verified in Case 2, no fields are omitted, the two fields are filled in normally and the data entered in the form_valid method is printed as follows: form.data.
Printing it results in:
<QueryDict: {'csrfmiddlewaretoken': ['SBRSJa0aw4iNJOMPwtQVsFL6V6y1cFMNGne9Kr0fA7YmtYeD8xshhDq6pc1mKjQs'], 'client': ['code2'], 'employee_of_turn': ['1']}>
Clearly it can be seen that the key employee_of_turn has an id value, not an object.
There it can be verified that the field employee_of_turn does not expect an object as such, at least not at that stage of the view.
from Problems with CreateView eyesight, django bug?
No comments:
Post a Comment