template_name not resolving for some views - django

My webapp was working fine, but after doing some ldap configurations (only changes regarding ldap in settings.py) my routing to certain pages seemed to brake. My urls.py seems to be in order but when i go to the view page i want to see it gives me another template.html file.
my urls.py
appname = 'app'
urlpatterns = [
path('logout/', views.LogOutView.as_view(), name='logout'),
path('', views.LoginView.as_view(), name='login'),
path('index/search', views.SearchView.as_view(), name="search"),
path('index/<slug:key>', views.EpicView.as_view(), name="detail"),
**path('index/exec_report', views.ExecView.as_view(), name = "exec"),
**path('index/exec_version_report', views.ExecVersionView.as_view(), name = "version"),
path('index/', views.IndexView.as_view()),
]
Now all the paths work well, but the 2 with ** next to them are the ones returning with the EpicView template
So in my index.html is where you click on a search to bring you to index/exec_version_report
index.html
<form method="GET" action = "{% url 'app:version' %}">
<select name ="versionA" >
<option value = 0>0</option>
</select>
<select name = "versionB">
<option value = 4.2> 4.2</option>
<option value = 4> 4.0</option>
</select>
<input type="submit" value="Search"/>
</form>
Now the url routing is correct when i click on "Search" but it is giving me the wrong template, but you can see that the template_name is not resolving to the one i had given it:
class ExecVersionView(LoginRequiredMixin, TemplateView):
template_name= 'APP/exec.html'
def get(self, request, *args, **kwargs):
self.versionA = request.GET.get('versionA','')
self.versionB = request.GET.get('versionB','')
return super().get(request, *args, **kwargs)
def get_context_data(self, **kwargs):
versionBint = Version(self.versionB)
versionAint = Version(self.versionA)
context = super(ExecVersionView, self).get_context_data(**kwargs)
open_low = ExecVersion.objects.filter(version__gte= versionAint, version__lte=versionBint, severity = 'Low', status='Open')
context['open_low'] = open_low
return context
Now for some reason this view will give me the wrong template file, And this is doing it to both of those ** routes/views
I am 100% certain that this is the correct .html file location

"index/exec_report" matches the path "index/<slug:key>" and Django returns the first path that matches. So it returns the detail view with key="exec_report".
Just move your detail path with the slug to a position after the two paths that don't work.

Related

passing a value in anchor tag in django

So I'm in my profile page & want to edit my profile so I click edit button ,it takes me to a edit page where I have two buttons 'save'(inside form tag) & 'Exit'. Now if I click exit I want to get redirected to profile page of same person again. what input should I pass in below tag to do this?
(<button>Exit</button>
adding urls.py
urlpatterns = [
path('',views.home, name='home'),
path('login/',views.loginp, name='login'),
path('profile/<str:ck>/',views.profile, name='profile'),
path('Edit_profile/<str:ck>/',views.Edit, name='Edit'),
path('logout/',views.logoutp, name='logout'),
path('register/',views.register, name='register'),
]
page where my button is located
<form method="POST">
{% csrf_token %}
{{form.as_p}}
<input type ="submit" value="Save">
</form>
<button>Exit</button>
For going back to particular profile you will need a url with profile/int:id and have to pass unique id of that particular profile in your url while calling exit.
Below is the sample you can do it where profile.id contains value of id of a profile.
<button>Exit</button>
i am not agree with other answers.
If you on your profile page, it means you are logged in.
In this case - you don't need to define user.pk, and it is better for usability - i can simply save the link mydomain/profile instead of mydomain/profile/user_pk.
But you should define, how you get an user from Request.
class ProfileView(LoginRequiredMixin, DetailView):
model = User
def get_object(self, *args, **kwargs):
self.kwargs['pk'] = self.request.user.pk
return super().get_object(*args, **kwargs)
I am shure - this is the better solution, than send pk in url.
LoginRequiredMixin- default django mixin for GCBV
DeteilView - django GCBV
More here:
https://docs.djangoproject.com/en/4.1/topics/auth/default/#django.contrib.auth.mixins.LoginRequiredMixin
and
https://docs.djangoproject.com/en/4.1/ref/class-based-views/generic-display/#detailview

Does This Hierarchy work with ListView? Getting NoReverseMatch Error

I'm running into an issue debugging the following error:
Reverse for 'tasks' with arguments '('',)' not found. 1 pattern(s) tried: ['customer/(?P[-a-zA-Z0-9_]+)/tasks/$']
However, I'm pretty certain that my url parameters are correct and without typos. The url and page worked fine with a function based view, the problem started when I changed to a ListView.
Template:
<a href="{% url 'customerportal:tasks' object.slug %}" class="nav-link">
I also tried:
<a href="{% url 'customerportal:tasks' slug=object.slug %}" class="nav-link">
<a href="{% url 'customerportal:tasks' slug=object.slug|slugify %}" class="nav-link">
DetailView - passing slug param to url
class ProjectDetailView(DetailView):
model = Project
template_name = 'customerportal/customer_portal.html'
def get(self, request, *args, **kwargs):
self.object = self.get_object()
if not self.object.access_verification(request.user):
raise PermissionDenied()
context = self.get_context_data(object=self.object)
return self.render_to_response(context)
My ListView (errors):
class TaskListView(ListView):
model = Task
template_name = 'customerportal/tasks.html'
def get_queryset(self):
self.project = get_object_or_404(Project, slug=self.kwargs['customer_portal'])
return Task.objects.filter(project=self.project.id)
URLs:
path('<slug:slug>/', ProjectDetailView.as_view(), name='customer_portal'),
path('<slug:customer_portal>/tasks/', TaskListView.as_view(), name='tasks'),
I've confirmed that I'm passing the right slug by printing it. The slug parameter is from a parent directory as seen in the urls.py above. I'm guessing ListView doesn't work this way? If not is there a way I could maintain this structure, or do I have to switch back to a function based view in order to get this to work?
Thanks.
there is 2 things to sort out:
your error message says that there is a path that looks similar to this:
path('customer/<slug:customer_portal>/tasks/', TaskListView.as_view(), name='tasks'),
but your paths do not match that pattern of the error message - maybe you edited the paths after the error appeared.
the error type "... arguments '('',)' ..." always means that the parameter in your {% url ... %} statement is empty. In your case that would mean object.slug is empty
Please check what you handover to the template as object.slug

Login Required Mixin acting up on a view where i didn't even include it(django)

So, i want my website's content only to be visible to the registered users, so i have put "LoginRequiredMixin" amd "#login_required" tags on most of my views except login and register views. Now, for registration, i want to give the registrants a choice before registering (whether they are current university students or alumni/recent graduates), this is how i am doing this:
class choice(View):
template = "network/choice.html"
def get(self, request):
form = ChoiceForm()
return render(request, self.template, {
"form": form,
"message": "Are you a curent student or an alumni/about to graduate"
})
def post(self, request):
form = ChoiceForm(request.POST)
if form.is_valid():
current = form.cleaned_data["current"]
if current:
return HttpResponseRedirect('accounts/register/current')
else:
return HttpResponseRedirect('accounts/register/alum')
where ChoiceForm just contains a boolean field, and "register/str:type" is my registration URL.
But after i submit the Choice Form:
<form action="{% url 'network:choice' %}" method="post">
{% csrf_token %}
{{ form|crispy }}
<br>
<input type="submit" value="Proceed"
</form>
the url to which i am taken to is:
/accounts/login/?next=/register/current
(i have not included any authentication check on the registration view, that won't make any sense lol)
Where i might have gone wrong is:
because i want anyone truing to access a restricted page to be redirected to the login page, i have defined my Urlpattern as follows:
path('accounts/login/', views.login_view.as_view(), name="login_view"),
path('accounts/register/<str:type>', views.register.as_view(), name="register"),
where 'accounts/login' is the path which django redirects to with the login_required tag. Did i do something wrong here?
This is my register view, although i am pretty sure that's not where the problem is as this view isn't even loading up even if i type in the url 'register/current'. I am still being redirected to accounts/login/?next=/register/current
Urlpatterns:
path('', views.index, name='index'),
path('new/<str:type>', views.new_page.as_view(), name="new"),
path('<str:type>/<str:name>', views.page.as_view(), name="page"),
path('logout', views.logout_view, name="logout_view"),
path('accounts/login/', views.login_view.as_view(), name="login_view"),
path('accounts/register/<str:type>', views.register.as_view(), name="register"),
path('choice', views.choice.as_view(), name="choice"),

Django Open and View a PDF(stored in AWS) in a new Tab

I have a model that stores a PDF file. On the DetailView of that Model I would like to have a link to view the PDF in a new tab. There are similar questions on here that I've used to get this far, but it looks like they're for local PDFs. My PDFs are stored as Media on AWS.
This is what I have right now:
plans/models.py
class PlanSet(PlanModel):
...
class PlanSetPDF(models.Model):
planset = models.ForeignKey(PlanSet)
PDF = models.FileField(upload_to='planPDFs')
created = models.DateField(auto_now_add=True)
added_by = models.ForeignKey(settings.AUTH_USER_MODEL, null=True)
plans/views.py
class PlanSetDetailView(DetailView):
model = PlanSet
template_name = "plan_detail.html"
def get_context_data(self, **kwargs):
context = super(PlanSetDetailView, self).get_context_data(**kwargs)
context['now'] = timezone.now()
return context
def view_pdf(request, pk):
pdf = get_object_or_404(PlanSetPDF, pk=pk)
image_data = open(pdf.PDF.url, "rb").read()
return HttpResponse(image_data, contenttype='application/pdf')
plans/urls.py
urlpatterns = [
url(r'^(?P<pk>\d+)/$', plan_detail, name='detail'),
url(r'^(?P<pk>\d+)/pdf/$', view_pdf, name='view_pdf'),
]
urls.py:
url(r'^plans/', include(plan_sets.urls, namespace='plans')),
template:
{% for pdf in object.plansetpdf_set.all %}
<a href="{% url 'plans:view_pdf' pdf.pk %}">
<span class="glyphicon glyphicon-file" aria-hidden="true"></span>PDF</a>
{% endfor %}
I'm recieving a builtin.OSError:[Errno 22] Invalid Argument: 'https://link_to_PDF_file_on_amazon'
It looks like Python can't open the file. I've looked around and I can't find any answers. Can one of you show me where I'm going wrong? Thanks.
I can't see the point of your view_pdf view at all. All it does is open the PDF via its URL, download it, and then re-send it to the browser. Why bother? You should just link directly to the PDF's url; and when you do so you can tell the browser to open it in a new tab:
<a href="{{ pdf.PDF.url }}" target="_new">

Django issue - NoReverseMatch

I'm working on extending Horizon to include a custom app.
In that app, I have a DataTable:
class WorkloadsTable(tables.DataTable):
name = tables.Column("name", verbose_name=_("Name"))
description = tables.Column("description", verbose_name=_("Description"))
image = tables.Column("image", verbose_name=_("Image"))
flavor = tables.Column("flavor", verbose_name=_("Flavor"))
class Meta:
name = "workloads_table"
verbose_name = _("Workloads Table")
table_actions = (CreateNewWorkload, DeleteWorkload)
row_actions = (UpdateWorkload, DeleteWorkload)
which has a LinkAction:
class UpdateWorkload(tables.LinkAction):
name = "update"
verbose_name = _("Edit Workload")
url = "horizon:mydashboard:workloads_panel:update"
classes = ("ajax-modal",)
icon = "pencil"
def get_link_url(self, datum):
base_url = super(UpdateWorkload, self).get_link_url(datum)
workload_id = self.table.get_object_id(datum)
reversed = urlresolvers.reverse(self.url, args=[workload_id])
print reversed
return urlresolvers.reverse(self.url, args=[workload_id])
This LinkAction points to a routce in my urls.py:
WORKLOADS = r'(?P<workload_id>[^/]+)/%s$'
urlpatterns = patterns('',
url(r'^create/$', views.CreateView.as_view(), name='create'),
url(WORKLOADS % 'update', views.UpdateView.as_view(), name='update'),
url(r'^$', views.IndexView.as_view(), name='index'),
)
The issue is: When I enter the following url:
http://localhost:9000/mydashboard/workloads_panel/3/update
I get: NoReverseMatch: Reverse for 'update' with arguments '()' and keyword arguments '{}' not found. 1 pattern(s) tried: [u'mydashboard/workloads_panel/(?P<workload_id>[^/]+)/update$']
Where am I going wrong?
I guess the solution to your problem lies in the _update.html where you have to include the URL as,
{% block form_action %}
{% url 'horizon:mydashboard:workloads_panel:update' workload.id %}
{% endblock %}
while the workload.id is the object's id that you get in views.py in get_context_data function:
def get_context_data(self, **kwargs):
context = super(## the class name ##, self).get_context_data(**kwargs)
try:
context['workload'] = ##your API call ##(self.request,
self.kwargs['id'])
except Exception:
exceptions.handle(self.request)
return context
May be this will help you to resolve the error.
Well now the answer is quite simple. There is no matching URL for this reverse call:
{% url 'horizon:mydashboard:workloads_panel:update' %}
The update named URL pattern requires a valid workload_id argument matching your regex [^/]+