Using CreateView, I am displaying a form that has a header set in the admin panel. I have no idea how to do it anymore because the variable set in context is not visible in html template. Otherwise, the variable is visible, but no form fields are displayed.
html file:
<div class="navbar">
<div class="image">
<img src="{% static 'images/logo.png' %}">
</div>
<div class="text">
<h1>{{name}}</h1>
</div>
</div>
<div class="card">
<form method="POST" action="">
{% csrf_token %}
{{ form.as_p }}
<input class="button" type="submit" value="Submit">
</form>
</div>
In this case, the entire form is shown correctly, but the header is not displayed (the content is empty). views.py:
class ItemCreate(CreateView):
template_name = 'form/additem.html'
model = Parts
fields = ['number', 'item']
success_url = reverse_lazy('parts_list')
def form_valid(self, form):
username = self.request.user.get_full_name()
form.instance.user = username
form.instance.desc = getDescFromDB(form.cleaned_data['number'])
return super(ItemCreate, self).form_valid(form)
def get(self, request):
match checkUserGroup(self.request.user):
case "Service":
return redirect("/")
case "Shop":
context = {
'name': getHeader('PartsForm')
}
return super().get(request, context)
In this case, the header displays correctly, but the form does not display (no form field is visible). views.py:
class ItemCreate(CreateView):
template_name = 'form/additem.html'
model = Parts
fields = ['number', 'item']
success_url = reverse_lazy('parts_list')
def form_valid(self, form):
username = self.request.user.get_full_name()
form.instance.user = username
form.instance.desc = getDescFromDB(form.cleaned_data['number'])
return super(ItemCreate, self).form_valid(form)
def get(self, request):
match checkUserGroup(self.request.user):
case "Service":
return redirect("/")
case "Shop":
context = {
'name': getHeader('PartsForm')
}
return render(request, self.template_name, context)
getHeader and checkUserGroup functions (work properly):
def getHeader(form):
title = Header.objects.get(name=form)
return title.title
def checkUserGroup(user):
if (user.groups.filter(name='Service').exists()):
return "Service"
elif (user.groups.filter(name='Shop').exists()):
return "Shop"
else:
raise PermissionDenied()
I know that my code must contain a lot of bugs, but I'm just starting to play with django and I don't understand everything yet.
You need to override the dispatch
method to check the user group and the get_context_data
method to add the header to the context.
Your code should look something like this (I haven't tested it):
class ItemCreate(CreateView):
template_name = 'form/additem.html'
model = Parts
fields = ['number', 'item']
success_url = reverse_lazy('parts_list')
def form_valid(self, form):
username = self.request.user.get_full_name()
form.instance.user = username
form.instance.desc = getDescFromDB(form.cleaned_data['number'])
return super(ItemCreate, self).form_valid(form)
def dispatch(self, request, *args, **kwargs):
match checkUserGroup(self.request.user):
case "Service":
return redirect("/")
case "Shop":
return super().dispatch(request, *args, **kwargs)
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["name"] = getHeader('PartsForm')
return context
Find more information about the dispatch method here and about adding extra context data here.