Facing issue in building nested URL in Django 1.11 - python

I am trying to create a Hierarchy where in homepage user has option to select Location in their Homepage and then once they select the location they get Respective Managers from that location and next once they select the managers they get respective associate.
Diagram -> (Homepage) all locations -on select specific location- > Managers - on select specific Manager- > List of associate (aligned to the manager )
Url Patterns:
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^(?P<hierarchy_id>[0-9]+)/$', views.managerview, name='managerview'),
url(r'(?P<associate_id>[0-9]+)/$', views.associatelist, name='associatelist'),
]
Views:
def index(request):
all_sites = Hierarchy.objects.all()
return render(request, "adash/index.html", {'all_sites': all_sites})
def managerview(request, hierarchy_id):
all_managers = Hierarchy.objects.get(pk=hierarchy_id)
return render(request, "adash/manager.html", {'all_managers': all_managers})
def associatelist(request, associate_id):
all_logins = Hierarchy.objects.get(pk=associate_id)
return render(request, "adash/associatelist.html", {'all_logins': all_logins})
Manager Html
<a class="list-group-item list-group-item-action"><h5 class = "text-monospace">{{ all_managers.direct_manager }}</h5></a>
Associate Html
<a class="list-group-item list-group-item-action"><h5 class = "text-monospace">{{ all_logins.login }}</h5></a>
currently am able to click on location and direct it to respective managers associated with that site but how to proceed to next step i.e click on manager and show list of associate.
Below is my model:
class Hierarchy(models.Model):
site = models.CharField(max_length=250)
direct_manager = models.CharField(max_length=250)
login = models.CharField(max_length=250)

Your direct_manager field needs to be a relationship, not a text field. This is a recursive relationship, where an instance of Hierarchy points to another instance which is its manager. So:
direct_manager = models.ForeignKey('self', related_name='direct_reports')
Now, given an instance of Hierarchy which is a manager, you can get all associates via the reverse relation:
associates = my_manager.direct_reports.all()

Related

Django 3.0.8 URL/Template/Routing Troubles "No reverse match"

first post so please forgive my ignorance as this is my first django app.
I am trying to create a template that displays all of the information regarding a specific "Ticket" from a list of all open tickets.
Unfortunately I am receiving following message whenever I attempt to add an anchor with a template url tag:
NoReverseMatch at /tickets/tasks/ Reverse for 'order' with arguments
'('',)' not found. 1 pattern(s) tried:
['tickets/order/(?P<ticket_id>[^/]+)/$']
Error message updated. Please see Update below.
And it is ONLY on this one HTML Template.
Below is all of the code I believe will be able to shed some light into the issue:
models.py:
from django.db import models
# Create your models here.
class Ticket(models.Model):
"""A basic support ticket"""
# User ticket title.
ticket_Name = models.CharField(max_length=50)
# When the request was submitted.
ticket_Submitted = models.DateTimeField(auto_now_add=True)
#Ticket Type
ticketTypeChoices=[
('Update', 'Article Edit/Update'),
('Addition', 'New Content/Article Request'),
('Typo', 'Article Typo/Formatting Issue'),
('Issue', 'Website Error/Issue'),
('Other', 'Other'),
]
# Type of ticket (Update, Addition, Typo, Site Issue)
ticket_Type = models.CharField(
max_length=50,
choices=ticketTypeChoices,
default= 'Other'
)
# Users Name
ticket_Contact = models.CharField(max_length=50)
# User Email (for follow up)
ticket_Email = models.EmailField(max_length=254)
# Article URL (if applicable)
ticket_URL = models.CharField(blank=True, max_length=254)
# User description of the issue.
ticket_Description = models.TextField()
#Ticket Status Choices
StatusChoices = [
('Pending', 'Pending'),
('Open', 'Open'),
('Complete', 'Complete'),
('Deferred', 'Deferred'),
('Awaiting Response', 'Awaiting Response'),
]
# Status of the Ticket
ticket_Status = models.CharField(
max_length=50,
choices=StatusChoices,
default= 'Pending'
)
# Comments from HelpDesk Staff
ticket_Comments = models.TextField(blank=True )
#Shows when the ticket was last saved.
ticket_Last_Updated = models.DateTimeField(auto_now=True)
def __str__(self):
"""Return a string representation of the model"""
return self.ticket_Name
views.py:
# Imports Models from the app
from . models import *
# Imports from the Forms List
from . forms import TicketForm
# Create your views here.
# View of all active tickets
def ticket(request):
tickets = Ticket.objects.all().order_by('-ticket_Submitted')
context = {'ticket': tickets}
return render(request, 'tickets/joblist.html', context)
# User can view details about a Ticket
def order(request, ticket_id):
order = Ticket.objects.get(id=ticket_id)
context= {'order': order}
return render(request, 'tickets/tix.html', context)
urls.py
from django.urls import path,include
from . import views
app_name='tickets'
urlpatterns = [
# Include default auth urls.
path('', include('django.contrib.auth.urls')),
# Support Ticket Form
path('submit/', views.submit, name='submit'),
# Contact Us Form
path('contact/', views.contact, name='contact'),
# TicketWeblist
path('tasks/', views.ticket, name='tasks'),
# Ticket Details
path('order/<str:ticket_id>/', views.order, name='order' )
]
Template (joblist.html):
{% for tickets in ticket %}
<tr>
<td>{{tickets.ticket_Name}}</td>
<td>{{tickets.ticket_Type}}</td>
<td>{{tickets.ticket_Contact}}</td>
<td>{{tickets.ticket_Status}}</td>
<td>{{tickets.ticket_Submitted}}</td>
<td>{{tickets.ticket_Last_Updated}}</td>
<td><a class="btn btn-sm btn-info" href="{% url 'tickets:order' ticket.id %}">View</a>
</tr>
{% endfor %}
After reviewing the code a dozen time, all I can be sure of is that is an issue that begins with the template anchor template url tag. (View) but no matter what format I try it comes up with this or a similar error.
UPDATE: At Mel's suggestion changed the url 'order' to 'tickets:order' and am now receiving the following message:
NoReverseMatch at /tickets/tasks/ Reverse for 'order' with arguments
'('',)' not found. 1 pattern(s) tried:
['tickets/order/(?P<ticket_id>[^/]+)/$']
I have been attempting to resolve this issue for about three days and was determined to solve it myself. Any type of help is appreciated and please feel free to point out any spaghetti code or lack of notes as well as I am looking for ways to grow.
Thanks!
You've set a namespace for your urls: app_name = 'tickets'
So correct reverse url would be.
{% url 'tickets:order' tickets.id %}
Can you try changing your order view function to this -
def order(request, ticket_id):
active_order = Ticket.objects.get(id=ticket_id)
context= {'order': active_order}
return render(request, 'tickets/tix.html', context)
You have created a separate urls.py for you app (it looks like it), so be sure to include namespace = tickets in your project urls.py file. And then in your template, you should do as follows:
{% url 'tickets:order' ticket.id %}
In other words, you need to include the name of the app as well.
I just saw that you are passing ticket.id from your template to the view, however there is no ticket.id anywhere in the code. Why don't you try passing a value that is there in the template. It should work.

How to change context in Django TemplateView based on url

I am stuck with an automation problem in that I have a django project with multiple subdomains, one for each council model instance. All of my models have a foreignfield of 'council' and that is how I am filtering the context of the sites by creating a separate view for each council that I add.
However I would like to somehow create a way to automate adding a view class with the right filtered context each time I add a model instance (Council).
Also I will need to add another url in the urlpatterns which again I am stumped maybe a bit of python could help there but the views are my main concern.
in my views:
class RedmarleyPageView(TemplateView):
template_name = "index.html"
def get_context_data(self, **kwargs):
council_no = 1
context = super (RedmarleyPageView, self).get_context_data (**kwargs)
context['members'] = Member.objects.filter (council=council_no)
context['roles'] = Role.objects.filter (council=council_no)
context['minutes'] = Minute.objects.filter (council=council_no)
context['agendas'] = Agenda.objects.filter (council=council_no)
context['documents'] = Document.objects.filter (council=council_no)
context['articles'] = Article.objects.filter (council=council_no)
context['councils'] = Council.objects.filter (id=council_no)
context['settings'] = Setting.objects.filter(council=council_no)
context['events'] = Event.objects.filter(council=council_no)
context['eventscategories'] = EventCategory.objects.all()
return context
urls:
url(r'^$', HomePageView.as_view(), name='home'),
url(r'^redmarley/', RedmarleyPageView.as_view(), name='redmarley'),
Redmarley in this context is the council inst. and I need it to be able to create a view and url like above for each instance.

Django - Custom admin action

I'm creating a custom django admin action to show the selected Projects in a chart which I have in a template, the problem that I'm having is that it's displaying all the existing projects and I want just to display the ones which the user selects in the admin part.
Here's the admin.py part which should filter the projects that the user had selected:
def show_gantt_chart_of_selected_projects(modeladmin, request, queryset):
selected = request.POST.getlist(admin.ACTION_CHECKBOX_NAME)
ct = ContentType.objects.get_for_model(queryset.model)
return HttpResponseRedirect("/xxx/?ct=%s&ids=%s" % (ct.pk, ",".join(selected)))
Here's the view.py part which should get the filtered projects:
def index(request):
projects = Project.objects.order_by('projectName') // I think this line could be the problem
context = {'projects': projects }
return render_to_response('xxx/ganttChart.html', context, context_instance=RequestContext(request))
When I open the chart site, the URL show the items that the user selected correctly(ex. http://x.x.x.x:xxxx/xxx/?ct=15&ids=10,1,3,5), but the chart still show all the existing projects.
The queryset parameter to the admin action already contains the selected projects. Alter to:
def show_gantt_chart_of_selected_projects(modeladmin, request, queryset):
ct = ContentType.objects.get_for_model(queryset.model) # why do you do this, you're not using it?
return HttpResponseRedirect("/xxx/?ct=%s&ids=%s" % (ct.pk, ",".join(queryset.values_list('pk', flat=True)))
BTW you should use reverse url resolving instead of hardcoding urls.
View, which I took the liberty to switch to a class-based version. You will want to do this eventually anyway:
from django.views.generic import ListView
class IndexView(ListView):
template_name = 'xxx/ganttChart.html'
context_object_name = 'projects'
model = Project
def get_queryset(self):
return Project.objects.filter(
pk__in=self.request.GET.get('ids','').split(','),
).order_by('projectName')
index = IndexView.as_view()

Django: How to return all models associated with a ForeignKey including all attributes of those models?

I have an app that I want to simply display all the URL links a page has associated with it when that page is visited.
It's similar to reddit in that there are many userpages (aka subreddits) and each page has an infinite possible amount of submitted links associated with it. The newlinkposts records are associated with a certain page via a ForeignKey.
Given a page, wow can I get all the related newlinkpost objects (including their corresponding likes, link comment, and post date) returned, in order to display them in a template?
My newlinkpost object is defined as follows:
class newlinkpost(models.Model):
newlink_tag = models.ForeignKey('userpagename') #tags link to which userpage it belongs to
link_comment = models.CharField(max_length=128) #comment to go along with post
post_date = models.DateField(auto_now=True, auto_now_add=False, null=False) #submission datestamp. later make it track editable posts if edit function is implemented
url = models.URLField(max_length = 1024, null=False) #actual submitted link
link_likes = models.IntegerField(null=False, default=0) #need to later create like button which will +1 the value
def __unicode__(self):
return self.url
When you add a ForeignKey within a model, as well as creating an attribute in the source model (in your case, newlinkpost) allowing you to find the one associated object, Django also creates a corresponding attribute inside the target model (in your case apparently userpagename).
By default this attribute is named after the source table, so in your case it will be newlinkpost_set.
That allows you to ask the question you're looking to answer: which newlinkpost objects have this userpagename?:
all_links = userpagename_instance.newlinkpost_set.all()
If you wish to apply additional filters, you can use the filter method instead:
some_links = userpagename_instance.newlinkpost_set.filter(...)
The newlinkpost_set attribute contains a RelatedManager object, which is a subtype of Manager, allowing you to use the same set of methods you could use on newlinkpost.objects, along with some additional methods allowing you to create new related objects.
Here's an example view using this technique: (this assumes you've got the model classes imported into the views module):
from django.shortcuts import render
def user_page(request, user_id):
page = userpagename.get(pk=user_id)
links = page.newlinkpost_set.all()
return render(
request,
"myapp/user_page.html",
{
page: page,
links: links,
}
)
...and here's an example of using that "links" variable in the template:
<ul>
{% for link in links %}
<li><a href="{{ link.url }}">{{ link.link_comment }} - {{ link.link_likes }} likes</li>
{% endfor %}
</ul>
You just use the reverse relationship.
my_userpagename.newlinkpost_set.all()

Django Pass additional parameters from a link to another view

I have a page drag.htmlwhich is served at this URL
http://localhost:8000/dashboard?wid=ca1480f&ref_url=localhost&adpart=left this page have a link
<a id="btn-start" href="/dashboard/save" class="btn">Save Reward</a>
when a user click this link it will redirect to a SaveRewardview where i want to save all the information present in link i.e wid=ca1480f&ref_url=localhost&adpart=left
urls.py
url(r'^dashboard$', login_required(CouponPageView.as_view()), name='dashboard'),
url(r'^dashboard/save$', login_required(SaveRewardView.as_view()), name=''),
model.py
class SaveReward(models.Model):
widget = EmbeddedModelField(Widget)
campaign = EmbeddedModelField(Campaign)
coupon_part = models.CharField(max_length=200)
saved_on = models.DateTimeField(auto_now_add=True)
def __unicode__(self):
return self.widget.widget_name
Views.py
class SaveRewardView(TemplateView):
#Here how i will get wid , ref_url, adpart which is present in url parameters
You can directly give parameters in url like this.
<a id="btn-start" href="/dashboard/?{{request.META.QUERY_STRING}}" class="btn">Save Reward</a>
url is:
url(r'^dashboard/$', login_required(CouponPageView.as_view()), name='dashboard'),

Categories

Resources