I am trying to show a detailed view of the contacts stored in a phonebook. The PhoneBook(id, name) is one of my models which is a foreign key to model Contact(id, first_name, last_name, phone_number, phone_book).
In my index page, there is a button which opens the phone book. After that, I want it such that the user may click on a phone book and the detailed view(first_name, last_name, phone_number) would be shown to them.
In view.py, I have a function which captures all the phonebook, passes it through context(dict). In my template, I have used a for loop to go through all the phonebooks and print them.
I am unable to direct the page to a detailed view. How do I get the phonebook the user clicked on? And how to direct the page from ./view to ./detail
# view.py
def view_phone_book(request):
all_phone_books = PhoneBook.objects.all()
context = {
'all_phone_books': all_phone_books
}
return render(request, "CallCenter/view_phone_book.html", context)
def detailed_view_phone_book(request):
all_contacts = Contact.objects.all().filter(phone_book=phone_book_user_clicked_on)
context = {
'all_contacts': all_contacts
}
return render(request, "CallCenter/detailed_view_phone_book.html", context)
# urls.py
urlpatterns = [
path('', index, name="index"),
path('create/', create_phone_book, name="create"),
path('add/', add_to_phone_book, name="add"),
path('view/', view_phone_book, name="view"),
path('detail/', detailed_view_phone_book, name="detailed_view")
]
# models.py
class PhoneBook(models.Model):
"""
Model to store customer to a phone book
"""
name = models.CharField(max_length=10, blank=False)
def __str__(self):
return self.name
class Contact(models.Model):
"""
Model to store customer to a phone book.
"""
first_name = models.CharField(max_length=50, blank=False)
last_name = models.CharField(max_length=50, blank=False)
phone_number = models.CharField(max_length=13, blank=False, unique=True)
phone_book = models.ForeignKey(PhoneBook, on_delete=models.CASCADE)
def __str__(self):
return self.phone_number
<!--view_phone_book.html-->
<table>
<tr>
<th>Phone Book</th>
</tr>
{% for phone_book in all_phone_books %}
<tr>
<form method="get" action="../detail/"><td>{{ phone_book }} </td></form>
</tr>
{% endfor %}
</table>
<!--detailed_view_phone_book.html-->
<table>
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Phone Number</th>
</tr>
{% for phone_detail in all_phone_detail %}
<tr>
<form>
<td>{{ phone_detail.first_name }}</td>
<td>{{ phone_detail.last_name }}</td>
<td>{{ phone_detail.phone_number }}</td>
</form>
</tr>
{% endfor %}
</table>
I am unable to go from ./view to ./detail. Also, how would I know which phone book the user clicked on?
I figured it out on how to make it work, and I'm answering it so that if anyone gets stuck in, it can help themselves.
# views.py
def view_phone_book(request):
all_phone_books = PhoneBook.objects.all()
context = {
'all_phone_books': all_phone_books
}
return render(request, "CallCenter/view_phone_book.html", context)
def detailed_view_phone_book(request, phone_book_id):
try:
all_contacts = Contact.objects.filter(pk=phone_book_id)
except Contact.DoesNotExist:
raise Http404("PhoneBook Does Not Exist!")
context = {
'all_contacts': all_contacts
}
return render(request, "CallCenter/detailed_view_phone_book.html", context)
#urls.py
urlpatterns = [
path('', index, name="index"),
path('create/', create_phone_book, name="create"),
path('add/', add_to_phone_book, name="add"),
path('campaign/', create_campaign, name="create-campaign"),
path('view/', view_phone_book, name="view-phone-book"),
path('detail/<int:phone_book_id>', detailed_view_phone_book, name="detail-view-phone-book"),
<!--view_phone_book.html-->
<body>
{% for phone_book in all_phone_books%}
{{ phone_book }}
<br>
{% endfor %}
Back To Home
</body>
<!--detailed_view_phone_book.html-->
{% if all_contacts %}
<table>
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Phone Number</th>
</tr>
{% for contact in all_contacts %}
<tr>
<form>
<td>{{ contact.first_name }}</td>
<td>{{ contact.last_name }}</td>
<td>{{ contact.phone_number }}</td>
</form>
</tr>
{% endfor %}
</table>
{% endif %}
Back To Home
I watched the Brain's CS50 video, which helped me. I'll suggest you do the same. He explains the concepts in a beginner-friendly way.
Related
I have a django template that I have implemented regroups in it. I have a problem with how to display some of the attributes from my model into the template in a table.
I have a couple of issues to address:
How can I display the remaining 4 attributes from the ImplementationMatrix model i.e implementation_status, implementation_summary, challenges, and wayforward to be displayed at the respective columns in the table on the template (index.html) without distorting the layout for each instance of ImplementationMatrix.
The last for loop in the templates displays only one item for subactivity while I have more than subactivity for the respective activity.
Is there any better way of implementing all this?
My Models:
class Strategy(TrackingModel):
"""
Stores all the strategies related to HSSP.
"""
strategy_name = models.CharField(
max_length=255, blank=True, null=True, default="")
class Meta(TrackingModel.Meta):
verbose_name_plural = "Strategies"
def __str__(self):
return self.strategy_name
class Intervention(TrackingModel):
intervention_name = models.CharField(
max_length=255, blank=True, null=True, default=""
)
strategy = models.ForeignKey(Strategy, on_delete=models.PROTECT)
class Meta(TrackingModel.Meta):
verbose_name_plural = "Interventions"
def __str__(self):
return self.intervention_name
class Activity(TrackingModel):
activity_name = models.CharField(
max_length=255, blank=True, null=True, default="")
intervention = models.ForeignKey(Intervention, on_delete=models.PROTECT)
class Meta(TrackingModel.Meta):
verbose_name_plural = "Activities"
def __str__(self):
return self.activity_name
class SubActivity(TrackingModel):
subactivity_name = models.CharField(
max_length=255, blank=True, null=True, default=""
)
activity = models.ForeignKey(Activity, on_delete=models.PROTECT)
class Meta(TrackingModel.Meta):
verbose_name_plural = "Sub Activities"
def __str__(self):
return self.subactivity_name
class ImplementationMatrix(TrackingModel):
"""
The class for keeping track the implementation of each action plan
"""
IMPLEMENTATION_STATUS = (
("ON PROGRESS", "ON PROGRESS"),
("DONE", "DONE"),
("NOT DONE", "NOT DONE"),
)
implementation_summary = models.TextField()
implementation_status = models.CharField(
choices=IMPLEMENTATION_STATUS, max_length=100, default="",
verbose_name="Matrix Implementation Status"
)
challenges = models.TextField()
way_forward = models.TextField()
sub_activity = models.ForeignKey(
SubActivity, on_delete=models.PROTECT, verbose_name='Sub-Actions')
def __str__(self) -> str:
return self.sub_activity.activity.intervention.strategy.strategy_name
My View:
#login_required(login_url="/login")
def matrix_implementation_list(request: HttpRequest) -> HttpResponse:
all_implementations = ImplementationMatrix.objects.filter(
active=True, deleted=False).select_related(
'sub_activity',
'sub_activity__activity',
'sub_activity__activity__intervention',
'sub_activity__activity__intervention__strategy')
context = {'all_implementations': all_implementations}
return render(request, 'index.html', context)
My template (index.html)
<div class="card-body">
{% regroup all_implementations by sub_activity.activity.intervention.strategy.strategy_name as strategy_list %}
<!-- Start Table section -->
<div class="table-responsive table-bordered">
<table class="table">
<thead class="thead-light">
<tr>
<th>Policy Statement</th>
<th>Action</th>
<th>Sub-Actions</th>
<th>Implementation Summary</th>
<th>Implementation Status</th>
<th>Challenges</th>
<th>Way Forward</th>
</tr>
</thead>
{% for strategy in strategy_list %}
<tr>
<td colspan="7" class="text-center"><strong>Priority Area {{ forloop.counter }}: {{ strategy.grouper }}</strong></td>
</tr>
{% regroup strategy.list by sub_activity.activity.intervention.intervention_name as intervention_list %}
{% for intervention in intervention_list %}
{% regroup intervention.list by sub_activity.activity.activity_name as activity_list %}
{% for activity in activity_list %}
{% regroup activity.list by sub_activity.subactivity_name as subactivity_list %}
{% for subactivity in subactivity_list %}
<tr>
{% if forloop.first %}
{% if forloop.parentloop.first %}
<td rowspan="{{ intervention.list|length }}">
{{ intervention.grouper|wordwrap:30|linebreaksbr }}
</td>
{% endif %}
<td rowspan="{{ activity.list|length }}">
{{ activity.grouper|wordwrap:30|linebreaksbr }}
</td>
{% endif %}
<td>
{{ subactivity.grouper|wordwrap:20|linebreaksbr }}
</td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
{% endfor %}
{% endfor %}
{% endfor %}
{% endfor %}
</table>
</div>
<!-- end Table Section -->
</div>
I was able to display the contents of the parent model in the last 'for loop' by doing the following:
<td>{{ subactivity.grouper|wordwrap:20|linebreaksbr }}</td>
<td>{{subactivity.list.0.implementation_summary|wordwrap:30|linebreaksbr}}</td>
<td>{{ subactivity.list.0.get_implementation_status_display }}</td>
<td>{{ subactivity.list.0.challenges|wordwrap:30|linebreaksbr }}</td>
<td>{{ subactivity.list.0.way_forward|wordwrap:30|linebreaksbr }}</td>
I am creating an app for a school schedule using Django. Admin users can currently add classes to a list. Student users can view that list but I want to create a button/link that will add that class object to a separate list that will act as their applied classes.
Models.py
class Class(models.Model):
def __str__(self):
return self.name
name = models.CharField(max_length=50)
crn = models.CharField(max_length=5, validators=[RegexValidator(r'^\d{1,10}$')])
grade_mode = models.CharField(max_length=50)
subject = models.CharField(max_length=3)
course_num = models.CharField(max_length=4, validators=[RegexValidator(r'^\d{1,10}$')])
section_num = models.CharField(max_length=3, validators=[RegexValidator(r'^\d{1,10}$')])
credit_hours = models.FloatField(validators=[MinValueValidator(0.0), MaxValueValidator(5.000)])
teacher = models.CharField(max_length=50)
Views.py
#login_required
#dec.student_required
def index(request):
class_list = Class.objects.all().order_by("-name")
# Allow for Posting of New Classes to Schedule.
if request.method == "POST":
form = ClassesForm(request.POST)
if form.is_valid():
form.save()
form = ClassesForm()
messages.success(request, "Class Added to Registry!")
else:
form = ClassesForm()
context_dict = {'classes': class_list,
'form': form}
return render(request, 'index.html', context=context_dict)
Index.HTML Add Button
<table>
<tbody>
{% if classes %}
{% for class in classes %}
<tr>
<td>Class Name: </td>
<td>Subject: </td>
<td>CRN: </td>
<td>Course Number: </td>
<td>Section Number: </td>
<td>Credit Hours: </td>
<td>Teacher: </td>
<td>Grade Mode: </td>
<td>Add Class</td>
</tr>
<tr>
<td>{{ class.name }}</td>
<td>{{ class.subject }}</td>
<td>{{ class.crn }}</td>
<td>{{ class.course_num }}</td>
<td>{{ class.section_num }}</td>
<td>{{ class.credit_hours }}</td>
<td>{{ class.teacher }}</td>
<td>{{ class.grade_mode }}</td>
<td>
<form method="GET">
{% csrf_token %}
<button class="addToSchedule" type="submit" value="add" name="Add Class">
Add Class
</button>
</form>
</td>
</tr>
{% endfor %}
</tbody>
{% else %}
<strong>There are no classes added.</strong>
{% endif %}
</table>
Image on Website.
So far I can print out the models on their own separate list as shown above but I don't know where to go in regards to the button or if a button is even the correct way of doing it. I want to click on a button and that model will be added and saved to the Added Classes section above.
I'm trying to render the name of all the products in templates. How do I do that in dashboard.html in the code given below? It is simple in ForeignKey but i cannot figure it out in ManyToMany Relationship.Please help
Models.py
class Product(models.Model):
CATEGORY=(('INDOOR','Indoor'),('OUTDOOR','Outdoor'))
name=models.CharField(max_length=100)
category=models.CharField(max_length=20,
choices=CATEGORY,
blank=True,
default='INDOOR',
help_text='Item Category',)
date_created=models.DateTimeField(default=timezone.now)
def __str__(self):
return self.name
class Order(models.Model):
STATUS=(('PENDING','Pending'),('OUT FOR DELIVERY','Out For Delivery'),('DELIVERED','Delivered'))
customer=models.ForeignKey(Customer,null=True,on_delete=models.SET_NULL)
date_created=models.DateTimeField(default=timezone.now)
product=models.ManyToManyField(Product)
status=models.CharField(max_length=20,
choices=STATUS,
blank=True,
default='PENDING',
help_text='Delivery Status',)
def __str__(self):
return self.customer.first_name
views.py
def home(request):
order=Order.objects.all()
context={
'order':order,
}
return render(request,'accounts/dashboard.html',context)
dashboard.html
<tr>
<th>Product</th>
<th>Date Orderd</th>
<th>Status</th>
<th>Update</th>
<th>Remove</th>
</tr>
{%for i in order%}
<tr>
<td>{{i}}</td> //in this line
<td>{{i.date_created}}</td>
<td>{{i.status}}</td>
<td><button>Update</button> </td>
<td> <button>Update</button></td>
</tr>
{%endfor%}
I am assuming that the first model in Model.py is your Product class (you forgot to past the class name):
In your template replace:
<td>{{ i }}</td>
for
{% for product in order.product.all %}
<td>{{ product.name }}</td>
{% endfor %}
I want to have template page with object(orders) list (another list, for another user). Like relations one to many. Where do i need to define that objects(order)(for exemple by id: order_id=1 and order_id=3) is assigned to user(driver) with id=1 etc?
I was trying to create Driver class and than set atribute driver in order Class like this.
form.py
class OrderForm(forms.Form):
telephone_regex = RegexValidator(regex=r'^\+?1?\d{9,15}$', message="Phone number must be entered in the format: '+999999999'.")
airport = forms.ChoiceField(choices=AIRPORT_CHOICES) ### Jeśli lotnisko jest celem podróży
direction = forms.ChoiceField(choices=DIRECTION_CHOICES) ## to pick_up < plane i odwrotnie!!!
adress = forms.CharField()
client = forms.CharField()
telephone = forms.CharField(validators=[telephone_regex])
flight_number = forms.CharField()
plane = forms.DateTimeField(input_formats=['%Y-%m-%d'])
pick_up = forms.DateTimeField(input_formats=['%Y-%m-%d'])
gate = forms.CharField()
company = forms.ChoiceField(choices=COMPANY_CHOICES)
driver = forms.ChoiceField(choices=DRIVER_CHOICES)
models.py
class Driver(models.Model):
name = models.CharField(max_length=30)
tel = models.CharField(max_length=17)
class Order(models.Model):
telephone_regex = RegexValidator(regex=r'^\+?1?\d{9,15}$',
message="Phone number must be entered in the format:
'+999999999'.")
airport = models.CharField(max_length=10, choices=AIRPORT_CHOICES)
direction = models.CharField(max_length=7, choices=DIRECTION_CHOICES)
adress = models.CharField(max_length=100, null=False, blank=False)
client = models.CharField(max_length=50, null=False, blank=False)
telephone = models.CharField(validators=[telephone_regex], max_length=17, blank=False)
flight_number = models.CharField(max_length=7)
plane = models.DateTimeField(null=True)
pick_up = models.DateTimeField(null=True)
gate = models.CharField(max_length=10, null=True, blank=True)
comapny = models.CharField(max_length=50, choices=COMPANY_CHOICES)
driver = models.ForeignKey(Driver, on_delete=models.CASCADE)
order_list.html
{% extends "base.html" %}
{% block content %}
{% if user.is_authenticated %}
<h1>Hi {{ user.username }}! Have a good tips!</h1>
{% else %}
<h1>You have to login to see your orders list</h1>
{% endif %}
<table class="table table-dark">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">client</th>
<th scope="col">telephone</th>
<th scope="col">flight number</th>
<th scope="col">airport</th>
<th scope="col">direction</th>
<th scope="col">adress</th>
<th scope="col">gate</th>
<th scope="col">plane</th>
<th scope="col">pick up</th>
</tr>
</thead>
{% for order in orders %}
<tbody>
<tr>
<th scope="row">{{ order.id }}</th>
<td>{{ order.client }}</td>
<td>{{ order.telephone }}</td>
<td>{{ order.flight_number }}</td>
<td>{{ order.airport }}</td>
<td>{{ order.direction }}</td>
<td>{{ order.adress }}</td>
<td>{{ order.gate }}</td>
<td>{{ order.plane }}</td>
<td>{{ order.pick_up }}</td>
<td>{{ order.driver }}</td>
</tr>
</tbody>
{% endfor %}
</table>
{% endblock %}
views.py
class OrderView(View):
def get(self, request, id):
orders = Order.objects.get(id=id)
users = User.object.get(id=id)
ctx = {
'orders': orders,
'users': users
}
return render(request, 'order.html', ctx)
class OrderListView(View):
def get(self, request):
form = OrderForm()
orders = Order.objects.all()
ctx = {'form': form, 'orders': orders}
return render(request, 'orders/order_list.html', ctx)
class AddOrderView(View):
def get(self, request):
form = OrderForm()
return render(request, 'orders/add_order.html', {'form': form})
def post(self, request, *args, **kwargs):
form = OrderForm(request.POST)
if form.is_valid():
order = Order.objects.create(airport=form.cleaned_data['airport'],
direction=form.cleaned_data['direction'],
adress=form.cleaned_data['adress'],
client=form.cleaned_data['client'],
telephone=form.cleaned_data['telephone'],
flight_number=form.cleaned_data['flight_number'],
plane=form.cleaned_data['plane'],
pick_up=form.cleaned_data['pick_up'],
gate=form.cleaned_data['gate'],
driver=form.cleaned_data['driver'])
return render(request, 'orders/add_order.html', {'form': form})
I expect to get form when i can input new order and select driver but I'm geting this:
http://dpaste.com/0PD363H
i am working on hotel booking app , in this i want to display the image of a hotel, based on user entered location . In this if i am displaying all hotels , i am able to display an image , if i am trying to displaying an image through some CRUD operations, i am unable to display it. Here are my code snippets.
class Customer_details(models.Model):
Name = models.CharField(max_length=128)
Age = models.IntegerField()
Mobile_number = models.IntegerField()
Email = models.EmailField()
Address = models.CharField(max_length=50)
Special_request = models.CharField(max_length=50, blank=True)
user = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
return self.Name
hotel_rating_choices = (
('1','1'),
('2','2'),
('3','3'),
('4','4'),
('5','5'),
('6','6'),
('7','7'),
)
class Hotel(models.Model):
Hotel_Name = models.CharField(max_length=50)
location = models.CharField(max_length=20)
no_of_rooms = models.IntegerField()
rating = models.CharField(max_length=1, choices=hotel_rating_choices, default=3)
hotel_img = models.ImageField(upload_to='hotel_images/')
uploaded_at = models.DateTimeField(auto_now_add=True)
user = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
return self.Hotel_Name
class Hotel_image(models.Model):
hotel_img = models.ImageField(upload_to = 'hotel_images/')
hotel = models.ForeignKey(Hotel, on_delete=models.CASCADE)
def __str__(self):
return self.hotel
Ignore the remaining models just concentrate on Hotel model .
`Below code snippet is my view regarding to query.
def get_hotels_by_location(request):
location = request.POST.get('location')
print(location)
location = location.lower()
result = Hotel.objects.values('Hotel_Name', 'rating', 'hotel_img').filter(location=location)
context = {'hotels': result, 'header': ['Hotel_Name', 'Rating', 'image'] }
return render(
request,
template_name='display_hotel_by_location.html',
context=context
)
And below is my django html template
<table class="table">
<tr>
{% for i in header %}
<th>
{{ i }}
</th>
{% endfor %}
</tr>
{% for element in hotels %}
<tr>
{% with i=0 %}
{% for key, value in element.items %}
{% if i == 2 %}
<td> <img src="{{ element.url }}" width = "300" height="300"> </td>
{% endif %}
<td> {{ value }} </td>
{% with j=i %}
j=j+1
i=j
{% endwith %}
{% endfor %}
</tr>
{% endfor %}
</table>
Please help me on this issue.
Change your Hotel_image class to add related name at your foreign to use it further
class Hotel_image(models.Model):
hotel_img = models.ImageField(upload_to = 'hotel_images/')
hotel = models.ForeignKey(Hotel, on_delete=models.CASCADE, related_name="hotel_images")
Clean up a bit your views, you dont really need use values in that case.
from .models import Hotel
def get_hotels_by_location(request):
location = request.POST.get('location').lower()
result = Hotel.objects.filter(location=location)
context = {'hotels': result, 'header': ['Hotel_Name', 'Rating', 'image'] }
return render(
request,
template_name='display_hotel_by_location.html',
context=context
)
HTML 1 - If you consuming the hotel_img from class Hotel use this one
<table class="table">
<tr>
{% for i in header %}
<th>{{ i }}</th>
{% endfor %}
</tr>
{% for hotel in hotels %}
<tr>
{% if forloop.counter0 == 2 and hotel.hotel_img %}
<td> <img src="{{ hotel.hotel_img.url }}" width="300" height="300"> </td>
{% endif %}
<td> {{ hotel.Hotel_Name }} </td>
</tr>
{% endfor %}
</table>
HTML 2 - If you using the class Hotel_image use like that
<table class="table">
<tr>
{% for i in header %}
<th>{{ i }}</th>
{% endfor %}
</tr>
{% for hotel in hotels %}
<tr>
{% for img in hotel.hotel_images %}
{% if img.hotel_img %}
<td> <img src="{{ img.hotel_img.url }}" width="300" height="300"> </td>
{% endif %}
{% endfor %}
<td> {{ hotel.Hotel_Name }} </td>
</tr>
{% endfor %}
</table>
More info about Django relations: https://docs.djangoproject.com/en/2.0/ref/models/fields/#django.db.models.ForeignKey.related_name
You can use Template Tags too to filter all images from your Hotel_Image
1 - Create one folder called templatetag and inside that one file inside it to be your templatetag inside your app folder
hotel/templatetags/hotel_templatetag.py
Inside the file put that code
from django import template
from .models import Hotel_image
register = template.Library()
def get_hotel_images(self):
return Hotel_image.objects.filter(id=self.id)
You Html should be like that
<table class="table">
<tr>
{% for i in header %}
<th>{{ i }}</th>
{% endfor %}
</tr>
{% for hotel in hotels %}
<tr>
{% for img in hotel|get_hotel_images %}
{% if img.hotel_img %}
<td> <img src="{{ img.hotel_img.url }}" width="300" height="300"> </td>
{% endif %}
{% endfor %}
<td> {{ hotel.Hotel_Name }} </td>
</tr>
{% endfor %}
</table>
More info about templatetags: https://docs.djangoproject.com/en/2.0/howto/custom-template-tags/