Django forms IntegerField value validation - python

I create form with IntegerField. Is possibility to validate input values on it, from defined list?
This is a API form, which connect to another DB. It's not based on model in project.
My form looks like that:
from django.core.exceptions import ValidationError
def validate_users(value):
users_list = [10012, 16115, 10505]
if value not in users_list:
raise ValidationError('Wrong number')
class PribilagesForm(forms.Form):
mslk_module_choices = (('1', 'one'),
('2', 'two'),)
workerId = forms.IntegerField(label='Nr. ewidencyjny', validators=[validate_users])
moduleName = forms.ChoiceField(label='Moduł', choices=mslk_module_choices)
When I input value from out of range validate_users, and submit form, I got ValueError, not information about wrong insert value.
view:
class TestFormPrivilegesView(TemplateView):
template_name = "SLK_WS_app/SLK/test.html"
def get(self, request):
form = PribilagesForm()
return render(request, self.template_name, {'form':form})
def post(self,request, **kwargs):
form = PribilagesForm(request.POST)
if form.is_valid():
workerId = form.cleaned_data['workerId']
moduleName = form.cleaned_data['moduleName']
# args = {'form': form, 'workerId':workerId, 'moduleName': moduleName, }
request_data = {'workerId': workerId,
'moduleName': moduleName}
context = super().get_context_data(**kwargs)
client = zeep.Client(wsdl=ws_source_slk_web_service)
find_privileges = client.service.FindUserModulePermission(**request_data)
data_find_privileges = find_privileges['usersModulesPermissions']['UserModulePermissionData']
privileges_list = []
privileges_data = namedtuple('FindUserModulePermission', ['workerId',
'workerFullName',
'moduleName',
'modifyDate',
'deleted',
]
)
for element in data_find_privileges:
privileges_list.append(privileges_data(element['workerId'],
element['workerFullName'],
element['moduleName'],
element['modifyDate'],
element['deleted'],
)
)
context['privileges_list'] = privileges_list
context['Date_time'] = datetime.datetime.today()
context['form'] = PribilagesForm()
return render(request, self.template_name, context)
render(request, self.template_name, context={'form': PribilagesForm()})```

At the bottom of your view inside the post method you have:
render(request, self.template_name, context={'form': PribilagesForm()})
This needs to have return like so:
return render(request, self.template_name, context={'form': PribilagesForm()})

Related

Django override __init__ form method using ModelForm

I have a foreign key (zone_set) as a choice field in a form. It should only display current project's zone_set . As you can see, It is not the case since it's displaying a zone_set: I belong to an other project, I should not be displayed here which does not belong to the current project.
Here is my form but it doesn't work.
class ODMatrixForm(forms.ModelForm):
class Meta:
model = ODMatrix
# fields = '__all__'
exclude = ('size', 'locked',)
def __init__(self, current_project=None, *args, **kwargs):
super().__init__(*args, **kwargs)
if current_project:
queryset = ZoneSet.objects.filter(project=current_project)
self.fields['zone_set'].queryset = queryset
The view creating the ODMatrix
def create_od_matrix(request, pk):
"""A roadnetwork depends on a project. It
must be created inside the project"""
current_project = Project.objects.get(id=pk)
form = ODMatrixForm(initial={'project': current_project})
if request.method == 'POST':
print(request)
od_matrix = ODMatrix(project=current_project)
# form = ODMatrixForm(request.POST, instance=od_marix)
form = ODMatrixForm(data=request.POST, instance=od_matrix)
if form.is_valid():
form.save()
messages.success(request, "OD matrix cessfully created")
return redirect('od_matrix_details', od_matrix.pk)
context = {
'project': current_project,
'form': form}
return render(request, 'form.html', context)
You created the __init__ as constructor of the Meta class, this should be a constructor of the ODMatrixForm, so:
class ODMatrixForm(forms.ModelForm):
# 🖟 part of ODMatrixForm, not Meta
def __init__(self, current_project=None, *args, **kwargs):
super().__init__(*args, **kwargs)
if current_project:
self.fields['zone_set'].queryset = ZoneSet.objects.filter(
project=current_project
)
class Meta:
model = ODMatrix
# fields = '__all__'
exclude = ('size', 'locked',)
In the view, you will need to pass the current_project when you construct an ODMatrixForm object:
from django.shortcuts import get_object_or_404
def create_od_matrix(request, pk):
current_project = get_object_or_404(Project, pk=pk)
if request.method == 'POST':
form = ODMatrixForm(current_project, request.POST, request.FILES)
if form.is_valid():
form.instance.project = current_project
form.save()
messages.success(request, 'OD matrix cessfully created')
return redirect('od_matrix_details', od_matrix.pk)
else:
form = ODMatrixForm(current_project=current_project)
context = {
'project': current_project,
'form': form
}
return render(request, 'form.html', context)
Note: It is often better to use get_object_or_404(…) [Django-doc],
then to use .get(…) [Django-doc] directly. In case the object does not exists,
for example because the user altered the URL themselves, the get_object_or_404(…) will result in returning a HTTP 404 Not Found response, whereas using
.get(…) will result in a HTTP 500 Server Error.

Can't get form class object in template view

I want to get the form object from self.Form
This is my form
class ActionLogSearchForm(forms.Form):
key_words = forms.CharField(required=False)
and I set form as form_class, however I can't fetch the form data in view
class ActionLogListView(LoginRequiredMixin, ListSearchView):
template_name = "message_logs/action_log.html"
form_class = ActionLogSearchForm
def get_queryset(self):
res = []
form = self.form ## somehow form is None
print(form.cleaned_data) # error occurs here. 'NoneType' object has no attribute 'cleaned_data'
I think this is the simplest set, but how can I make it work?
Try this:
from django.http import HttpResponseRedirect
from django.shortcuts import render
class ActionLogSearchForm(forms.Form):
key_words = forms.CharField(required=False)
class ActionLogListView(LoginRequiredMixin, ListSearchView, request):
form_class = ActionLogSearchForm
def get_queryset(self, request):
res = []
if request.method == 'POST':
form = self.form(request.POST)
if form.is_valid():
return HttpResponseRedirect('/thanks/')
else:
form = NameForm()
return render(request, 'message_logs/action_log.html', {'form': form})

django passing context data from post method

here is my views.py
class DoctorDetailView(generic.DetailView):
model = Doctor
context_object_name = "doctor"
template_name = "adminplus/pages/doctor_profile.html"
def get_context_data(self, **kwargs):
context = super(DoctorDetailView, self).get_context_data(**kwargs)
data = {
"edit_form": forms.DoctorEditForm(instance=self.object),
"password_change_form": forms.PasswordChangeForm(self.object.user),
}
context.update(data)
return context
def post(self, request, *args, **kwargs):
if request.POST.get("change-password"):
form = forms.PasswordChangeForm(request.POST)
if form.is_valid():
print("valid form here!")
# ...
else:
print("invalid form : ", form.errors)
return render(request, self.template_name, ?? )
I've no idea how can i pass get_context_data back to my template. (or anything that works.. idk new to django:)
~Thanks in advance
You can pass contex to render directly:
def post(self, request, *args, **kwargs):
# ...
context = self.get_contex_data(**kwargs)
return render(request, self.template_name, context=context)
You can do this on the return:
return render(request, self.template_name, context=self.context )

Unable to override post method of Django UpdateView

I have a update view in django project. I need to override the post method because I am using multiple modelform.
views.py:
class EmployeeUpdateView(LoginRequiredMixin, UpdateView):
"""
Update a created a employee
"""
login_url = '/authentication/login/'
template_name = 'employee/employee_update_form.html'
form_class = EmployeeAddModelForm
work_form_class = WorkExperienceForm
education_form_class = EducationForm
queryset = Employee.objects.all()
#success_url = reverse_lazy('employee:employee-list')
def get(self, request, *args, **kwargs):
id_ = self.kwargs.get("id")
employee_id = Employee.objects.get(id=id_)
work_info = WorkExperience.objects.get(employee=employee_id)
education_info = Education.objects.get(employee=employee_id)
return render(request, self.template_name, {
'form': self.form_class(instance=employee_id),
'work_form': self.work_form_class(instance=work_info),
'education_form': self.education_form_class(instance=education_info)
}
)
def post(self, request, *args, **kwargs):
form = self.form_class(request.POST)
work_form = self.work_form_class(request.POST, prefix='work_form')
education_form = self.education_form_class(request.POST, prefix='education_form')
# Check form validation
if form.is_valid() and work_form.is_valid() and education_form.is_valid():
instance = form.save()
work = work_form.save(commit=False)
education = education_form.save(commit=False)
work.employee = instance
education.employee = instance
work.update()
education.update()
return redirect('employee:employee-list')
return render(request, self.template_name, {
'form': form,
'work_form': work_form,
'education_form': education_form
}
)
When I press update button of my form, error is giving showwing "This field already exist". It means when i update the form is post data as a new form not as a update form.
Where is error in my post method?

Django : request.POST error "__init__() takes 1 positional argument but 2 were given"

I have a simple form in my Django project:
forms.py
class DamageListCriteria(forms.Form):
fromdate = forms.CharField(widget=forms.widgets.DateTimeInput(attrs={'type': 'datetime-local'}))
todate = forms.CharField(widget=forms.widgets.DateTimeInput(attrs={'type': 'datetime-local'}))
class Meta:
fields = ['fromdate','todate']
views.py
class DamageListCriteria(TemplateView):
template_name = "damage/damagelist_criteria.html"
def get(self, request):
form = DamageListCriteria()
general = General.objects.get(pk=1)
args = {
'form': form,
'general': general
}
return render(request, self.template_name, args)
def post(self, request):
general = General.objects.get(pk=1)
form = DamageListCriteria(request.POST)
args = {
'form': form,
'general': general
}
return render(request, self.template_name, args)
urls.py
url(r'damage/list/criteria/$', views.DamageListCriteria.as_view(), name="damage-list-criteria"),
when I try to post I am getting this error :
'__init__() takes 1 positional argument but 2 were given'
the error is on the form = DamageListCriteria(request.POST) line of code.
Thanks in advance for your time
This is because you defined your form class and view class with the same name. So change the class name of either view or form class.
or change your respective files as below,
forms.py(Changed form class name to DamageListCriteriaForm)
class DamageListCriteriaForm(forms.Form):
fromdate = forms.CharField(widget=forms.widgets.DateTimeInput(attrs={'type': 'datetime-local'}))
todate = forms.CharField(widget=forms.widgets.DateTimeInput(attrs={'type': 'datetime-local'}))
class Meta:
fields = ['fromdate', 'todate']
views.py (changed the references of form class)
class DamageListCriteria(TemplateView):
template_name = "damage/damagelist_criteria.html"
def get(self, request):
form = DamageListCriteriaForm()
general = General.objects.get(pk=1)
args = {
'form': form,
'general': general
}
return render(request, self.template_name, args)
def post(self, request):
general = General.objects.get(pk=1)
form = DamageListCriteriaForm(request.POST)
args = {
'form': form,
'general': general
}
return render(request, self.template_name, args)
You redefined your DamageListCriteria class in views.py. So, you're trying to instantiate your view class, instead of form.
Try changing your view name to DamageListCriteriaView, or/and form to DamageListCriteriaForm.

Categories