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 )
Related
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()})
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?
I want to use ajax in comments and reply sections of my blog application. In function based view everything is working fine, but I want to do it class based view.
***My function based view***
def post_detail(request, pk):
post = get_object_or_404(Post, pk=pk)
comments = Comment.objects.filter(post=post, reply=None).order_by('-id')
if request.method == 'POST':
comment_form = CommentForm(request.POST or None)
if comment_form.is_valid():
content = request.POST.get('content')
reply_id = request.POST.get('comment_id')
comment_qs = None
if reply_id:
comment_qs = Comment.objects.get(id=reply_id)
comment = Comment.objects.create(post=post,
user=request.user,
content=content,
reply=comment_qs)
comment.save()
else:
comment_form = CommentForm()
context = {
'title': 'blog',
'post': post,
'comments': comments,
'comment_form': comment_form,
}
if request.is_ajax():
html = render_to_string('blog/comments.html', context, request=request)
return JsonResponse({'form': html})
return render(request, 'blog/post_detail.html', context)
***My class based view***
class PostDetailView(FormMixin, DetailView):
model = Post
form_class = CommentForm
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
post = get_object_or_404(Post, id=self.object.id)
comments = Comment.objects.filter(post=post, reply=None).order_by('-id')
context['title'] = 'Blog Detail'
context['comments'] = comments
context['comment_form'] = self.get_form()
return context
def post(self, request, *args, **kwargs):
#if request.user.is_authenticated():
self.object = self.get_object()
form = self.get_form()
if form.is_valid():
content = request.POST.get('content')
reply_id = request.POST.get('comment_id')
comment_qs = None
if reply_id:
comment_qs = Comment.objects.get(id=reply_id)
comment = Comment.objects.create(post=self.object,
user=request.user,
content=content,
reply=comment_qs)
comment.save()
#return HttpResponseRedirect(self.object.get_absolute_url())
else:
return self.form_invalid(form)
if request.is_ajax():
html = render_to_string('blog/comments.html', context, request=request)
return JsonResponse({'form': html})
def get_success_url(self):
return reverse('post-detail', kwargs={'pk': self.kwargs['pk'], })
In my class based view in if request.is_ajax():
html = render_to_string('blog/comments.html', context,request=request)
return JsonResponse({'form': html})
part it shows the error that context is not defined. So how to fix this problem or how to include it in function, since I have already context.
There is no problem in my function based view code it is working as expected.
It's because. You use context variable but it not defined yet.
if request.is_ajax():
html = render_to_string('blog/comments.html', context, request=request)
return JsonResponse({'form': html})
Try this this get the context:
context = self.get_context_data(object=self.object)
You can see this by tracing the source code of DetailView, you'll see that DetailView inheriting from BaseDetailView and you will found this script to get the context
Hope this helpful!
in this method:
def post(self, request, *args, **kwargs):
...
...
if request.is_ajax():
html = render_to_string('blog/comments.html', context, request=request)
return JsonResponse({'form': html})
simple, you use context, but its not defined. Either pass it as parameter or define it somewhere as a variable
I want to be able to take the same form input and use it to do calculations (using different urls) for different products and send product results to a product template
I tried having a base class with get and post methods from which child classes(different product urls) will inherit especially the post method to remain DRY
from .models import InputForm
class InputView(TemplateView):
template_name = 'input.html'
def get(self, request, *args, **kwargs):
form = InputForm()
return render(request, self.template_name, {'form': form})
def post(self, request, *args, **kwargs):
form = InputForm(request.POST)
if form.is_valid():
cleaned_data = form.cleaned_data
a =cleaned_data['mbr_l']
b =cleaned_data['es_l']
c =cleaned_data['wic_l']
d =cleaned_data['br2_l']
length = a + b + c + d
qty = 0.8*length
return render(request, 'result.html', {'qty': qty})
else:
return render(request, self.template_name, {'form': form})
class B(InputView):
def post(self, request, *args, **kwargs):
qty2 = super().post(self, request, *args, **kwargs)
return super().render(request, 'result2.html', {'qty2': qty2})
url conf:
urlpatterns = [
path('product1', InputView.as_view()),
path('product2',B.as_view()),
]
templates:
template1
<td>{{qty1}}</td>
template2
<td>{{qty2}}</td>
I expect the url product2 in url conf to do calculation and send context(qty2) to results2.html but it always renders results.html with qty which is correct because B is inheriting InputView and all methods.I dont really expect the call to super of render method to be valid but that was the last of my many trials.
I have a FormView called LeagueTransferView based on a form LeagueTransferForm.
I'm trying to override get_context_data to add extra players to render in the template.
But get_context_data is never reached. It's working fine on other views like, DetailView, ListView,...
I'm missing something?
Below my configuration
View
class LeagueTransferView(FormView):
template_name = 'hockey/league/transfer_market.html'
form_class = LeagueTransferForm
success_url = ''
def get_context_data(self, **kwargs):
print('----NEVER REACHED----')
context = super(LeagueTransferView, self).get_context_data(**kwargs)
petitioner = get_object_or_404(Team, user=self.request.user.profile, league=self.kwargs['pk'])
context['players'] = Player.objects.filter(leagues=self.kwargs['pk']).exclude(teams=petitioner)
return context
def get(self, request, *args, **kwargs):
petitioner = get_object_or_404(Team, user=self.request.user.profile, league=self.kwargs['pk'])
form = self.form_class(initial={'league': self.kwargs['pk'], 'petitioner': petitioner})
form.fields['offered_player'].queryset = petitioner.players
return render(request, self.template_name, {'form': form})
def post(self, request, *args, **kwargs):
form = self.form_class(request.POST)
if form.is_valid():
transfer = form.save(commit=False)
team = Team.objects.filter(league=transfer.league, players__in=[transfer.requested_player])
if not team: # free agent
transfer.status = 1
messages.success(request, _('transfer succeeded'))
else:
print(team)
transfer.player_owner = team[0]
if transfer.petitioner.user is None: # bot team
transfer.status = 1
messages.success(request, _('transfer succeeded'))
else:
messages.success(request, _('transfer waiting for confirmation by player owner'))
transfer.save()
return HttpResponseRedirect(reverse('hockey_dashboard'))
petitioner = get_object_or_404(Team, user=self.request.user.profile, league=self.kwargs['pk'])
form.fields['offered_player'].queryset = petitioner.players
return render(request, self.template_name, {'form': form})
FORM
class LeagueTransferForm(forms.ModelForm):
class Meta:
model = Transfer
fields = ['league', 'requested_player', 'offered_player', 'player_owner', 'petitioner']
labels = {
'requested_player': _('Requested player'),
'offered_player': _('Offered player'),
}
widgets = {
'requested_player': forms.HiddenInput,
'league': forms.HiddenInput,
'player_owner': forms.HiddenInput,
'petitioner': forms.HiddenInput
}
Your code is never reaching get_context_data() because you have overridden the get() method and not calling the get_context_data() function there. You need to manually call the get_context_data() function at the time of passing context to render() in your code.
Instead of doing that, i would suggest you to try the below approach where instead of overrriding get() and returning your custom response, you only override what is necessary and let Django handle the rest.
class LeagueTransferView(FormView):
template_name = 'hockey/league/transfer_market.html'
form_class = LeagueTransferForm
success_url = ''
def get_context_data(self, **kwargs):
context = super(LeagueTransferView, self).get_context_data(**kwargs)
context['players'] = Player.objects.filter(leagues=self.kwargs['pk']).exclude(teams=self.petitioner)
return context
def get_initial(self):
initial = super(LeagueTransferView, self).get_initial()
initial['league'] = self.kwargs['pk'] # add custom data to initial
initial['petitioner'] = self.petitioner # add custom data to initial
return initial
def get_form(self, form_class=None):
form = super(LeagueTransferView, self).get_form(form_class)
# override the queryset
form.fields['offered_player'].queryset = self.petitioner.players
return form
def get(self, request, *args, **kwargs):
# only perform 1 query to get 'petitioner'
self.petitioner = get_object_or_404(Team, user=self.request.user.profile, league=self.kwargs['pk'])
return super(LeagueTransferView, self).get(request, *args, **kwargs)