Django Accessing Parent Data in templates from child data - python

So I've been search and trying to solve this question for hours and hours and I cant' seem to find an answer.
I have 2 different models flights and Destinations. The Destination is the Parent model, A flight can only have one destination but the Destination can have many flights (one to many relationship).
I would like to access this parent model on the details page of of the flight model. This details page is generated via the url routing and the slug of the flight. Here is what I have for the for the models, views and templates.
models:
class Flight(models.Model):
title = models.CharField( null=True, max_length=60, blank=True)
slug = models.SlugField(max_length=100, null=True, blank=True)
flight_destination = models.ForeignKey(Destination, null=True, blank=True, on_delete=models.SET_NULL)
class Destination(models.Model):
title = models.CharField( null=True, max_length=60, blank=True)
featuredimage = models.ImageField(null=True, blank=True, upload_to ='media/')
slug = models.SlugField(max_length=100, null=True, blank=True)
Each of these classes has an id for its primary key and I've connected all my flights to the correct destination.
Here is what I have for my view.
def flight_detail(request, slug):
return render(request,"flight/detail.html",context= {'flight': Flight.objects.get(slug=slug), 'destination': Destination.objects.filter(id= Flight.objects.get(slug=slug).flight_destination_id)})
Here is the template but it which doesn't throw an error but it displays nothing
<h3 class="pb-3">
{{ destination.title }}
</h3>
I feel like this should be an extremely common question with tons of straight forward answers but I can't seem to find anything. Any help would be greatly appreciated.

You can access the flight_destination directly in the flight object, you could get the flight object outside the render method to make it clearer and have access to the destination attribute object like this:
def flight_detail(request, slug):
flight = Flight.objects.get(slug=slug)
return render(request, "flight/detail.html",
context = {
'flight': flight,
'destination': flight.flight_destination
}
)

Exactly what I was looking for, thanks! From the time that I made this post I was actually able to get my original one to work using a forloop on the template, but I feel your solution is much cleaner and a more proper way of achieving this. Thanks again!

Related

display objects from inline model in DetailView

I have 2 models Product and Resource. Resource has to be a TabularInline model in my admin panel. I am struggling with filtering resource titles that are related only to this product. Since it is a ForeignKey I should use select_related but I am not sure how to use it in my case. For now, the loop in my HTML file gives me all sales files (from all products).
models.py
class Product(models.Model):
id = models.AutoField(primary_key=True)
title = models.CharField('title', max_length=400, default='')
slug = models.SlugField(unique=True, blank=True, max_length=600)
class Resource(models.Model):
id = models.AutoField(primary_key=True)
type = models.CharField(max_length=32, choices=RESOURCE_TYPE, default='sales')
title = models.CharField(max_length=400, blank=False, null=False, default='')
related_files = models.FileField(upload_to='recources/', null=True, blank=True)
publish = models.DateTimeField('Published on', default=timezone.now)
resources = models.ForeignKey(Product, default='', on_delete=models.PROTECT, null=True, related_name='resources')
admin.py
class Resourceinline(admin.TabularInline):
model = Resource
class ProductAdmin(ImportExportModelAdmin):
inlines = [
Resourceinline,
]
resource_class = ProductResource
admin.site.register(Product, ProductAdmin)
views.py
class ProductDetailView(DetailView):
template_name = 'ProductDetailView.html'
model = Product
def get_context_data(self, **kwargs):
context = super(ProductDetailView, self).get_context_data(**kwargs)
resources_sales = Resource.objects.select_related('resources').filter(resources_id =1, type='sales') # not sure what to put here
context['resources_sales'] = resources_sales
return context
ProductDetailView.html
{% for resource in resources_sales.all %}
<p>{{resource.title}}</p>
{% endfor %}
Question
Where am I making the mistake and how can I display resource objects that are related to type=sales and are related only to this product in DetailView.
Edit
I realized that there is a column named resources_id that is connecting both models. Now I am struggling to filter it by id of current DetailView. I put resources_id=1 in my views.py but it must relate to DetailView that user is currently looking at. I tied to put resources_id=self.kwargs['id'] but it gives me KeyError at /product/test-product/ 'id' How can I do that?
since you are using generic DetailView you can refer to the current object with self.get_object(). actually that return the single object that view display. however you can use instateself.object too.
so you can filter the Product related Resources using Resource.objects.filter(resources=self.get_object(), type='sales')
you can read more Single object mixins

Django - Making a Reservation system

As a part of a task, I created an "apartment listings" website.
I managed to get that done, but now I need to make a "reservation system" for it.
The basic idea is that a logged in user can select an apartment from the listed apartments, pick a "start_date" and an "end_date" (if the apartment already isn't booked ) and book the apartment.
Im a total Django newbie, and need some pointers in order to start somewhere with this task.
I have an Apartment model which contains all of the Apartments info that I use to print everything out with the template.
I'm using the provided django user models to register / log-in.
What kind of model do I need for the reservation, and how could I connect everything ?
I tried making a reservation model, but I got no idea where to go next.
I'm not asking for you to solve this for me, I'm asking for someone to explain (if possibile in detal) to me how could I go on about achieving this on my own.
this is my apartment model:
class Apartment(models.Model):
title = models.CharField(max_length=200)
address = models.CharField(max_length=200)
city = models.CharField(max_length=100)
state = models.CharField(max_length=100)
zipcode = models.CharField(max_length=20)
description = models.TextField(blank=True)
price = models.IntegerField()
bedrooms = models.IntegerField()
bathrooms = models.DecimalField(max_digits=2, decimal_places=1)
garage = models.IntegerField(default=0)
size = models.IntegerField()
photo_main = models.ImageField(upload_to='photos/%Y/%m/%d/')
photo_1 = models.ImageField(upload_to='photos/%Y/%m/%d/', blank=True)
photo_2 = models.ImageField(upload_to='photos/%Y/%m/%d/', blank=True)
photo_3 = models.ImageField(upload_to='photos/%Y/%m/%d/', blank=True)
photo_4 = models.ImageField(upload_to='photos/%Y/%m/%d/', blank=True)
in_rent = models.BooleanField(default=False)
list_date = models.DateTimeField(default=datetime.now, blank=True)
def __str__(self):
return self.title
Thank you so much !
Your assumption for making a Reservation object would be correct.
You'll want to link those reservations to the Apartment in question. Django supports these kind of relationships through their ForeignKey and ManyToManyField.
These fields support linking of one-to-one, one-to-many, and many-to-many relationships.
In your case, one Apartment can have many Reservations, which means you need to have a field in your Reservation pointing to a single Apartment, which can be done using a ForeignKey
Your model should look something like this:
Reservation(models.Model)
apartment = models.ForeignKey(to=Apartment, related_name='reservations',
on_delete=models.Cascade)
start_date = models.DateField()
end_date = models.DateField()
To retrieve all reservations for an appartment, you can simply use apartment.reservations since we've defined a related_name in the ForeignKey field.
You can even filter for specific dates by doing Reservations.objects.filter(apartment=apartment, start_date__gte=<your_start_date>, end_date__gte<your_end_date>)

Using Model.objects.all() as a blueprint for a secondary table entry

I am having a bit of trouble with the logic of how this should work so I am hoping it is possible.
I figured out 1 possible solution that is written as an answer below, I will accept it in a few days, but if someone comes up with a better solution, I will negate any answer I post.
Overall I am working on an Apartment Move-Out/Move-In Inspection Application in Django, and in both portions I have universal Locations that must be inspected for each report. I have allowed the InspectionLocations objects to be updated/submitted by clients, which is presenting an issue in how submitted reports should be stored in my Database.
What I want is to use the InspectionLocations table as a blueprint to build an Inspection Report for Move-Ins where the form-fields are generated based on the InspectionLocations objects' location, status, and information attributes/fields.
My issue is right at this point, how do I reference those values as a blueprint to build a report submission when the number of fields in the InspectionLocations can change?
from django.db import models
from apps.units.models import Unit
class Inspections(models.Model):
class Meta:
abstract = True
id = models.AutoField(primary_key=True)
inspection_date = models.DateField()
submitted_by = models.ForeignKey(
'users.CustomUser',
default=None,
null=True,
on_delete=models.SET_NULL,
db_column='submitted_by')
last_update = models.DateTimeField(auto_now=True)
date_added = models.DateTimeField(auto_now_add=True, editable=False)
class MoveInInspections(Inspections):
unit = models.ForeignKey(Unit, on_delete=models.CASCADE, db_column='unit_id')
# should have reference to all InspectionLocation items as reference for submission, how?
class MoveOutInspections(Inspections):
unit = models.ForeignKey(Unit, on_delete=models.CASCADE, db_column='unit_id')
date_notice_given = models.DateField(blank=True, null=True, default=None)
date_vacated = models.DateField(blank=True, null=True, default=None)
# should have reference to all InspectionLocation items as reference for submission, how?
class InspectionLocations(models.Model):
'''
Defualt Inspection Locations are created when a
client is created using code like this:
InspectionLocation.objects.get_or_create(location='Living Room')
InspectionLocation.objects.get_or_create(location='Dining Room')
InspectionLocation.objects.get_or_create(location='Kitchen')
InspectionLocation.objects.get_or_create(location='Bedroom')
InspectionLocation.objects.get_or_create(location='Bathroom')
InspectionLocation.objects.get_or_create(location='Other')
'''
id = models.AutoField(primary_key=True)
location = models.CharField(max_length=50)
status = models.BooleanField(default=None)
information = models.TextField(default=None, blank=True)
I have tried ManyToMany fields and FKs but I cannot seem to get the logic working as anytime an object references an InspectionLocations object it is universally changing data for every report, which is leading be to the idea that I somehow need to use it as a blueprint.
I didn't post this in my question because it was getting long, but my best option so far seems to be to use a Django JSONField (as I am using Postgres), like so:
from django.contrib.postgres.fields import JSONField
class MoveInInspections(Inspections):
unit = models.ForeignKey(Unit, on_delete=models.CASCADE, db_column='unit_id')
data = JSONField()
class MoveOutInspections(Inspections):
unit = models.ForeignKey(Unit, on_delete=models.CASCADE, db_column='unit_id')
date_notice_given = models.DateField(blank=True, null=True, default=None)
date_vacated = models.DateField(blank=True, null=True, default=None)
data = JSONField()
To where I store the values of the InspectionLocations object's in a Dictionary

Django Queryset for Getting Feeds from Following Users

I am trying to get feeds from following users such as Facebook, Instagram, and Twitter. I wrote a view to show feeds from following people.
class Following(View):
def get(self, request):
user = request.user
posts = models.Post.objects.filter(creator__in=user.following.all()).order_by('created_date')[:5]
I was worrying if it might cause a performance issue due to user.following.all() part. I do not know why
filter(creator=user.following)
does not work.
following is a self-referencing ManyToManyField.
followers = models.ManyToManyField("self", blank=True)
following = models.ManyToManyField("self", blank=True)
Is there any better solution?
I have another issues with counting a number of ManyToManyFields.
class Popular(View):
def get(self, request):
user = request.user
posts = models.Post.objects.annotate(number_of_likes=Count('likes'), number_of_comments=Count('comments')).filter(Q(channels__users=user) & (Q(number_of_likes__gte=5) | Q(number_of_comments__gte=5))).order_by('created_date')[:5]
It is so long because likes__count and comments__count did not work. The only case I found on the internet that works was this, using annotate(). Is there a better solution for this? I want to filter out posts that have channels a user is subscribing and among them, I want to only show number of likes or number of comments are above certain range. Why does this not work?
models.Post.objects.filter(Q(channels__users=user) & (Q(likes__count__gte=5) | Q(comments__count__gte=5))).order_by('created_date')[:5]
class Comment(news_models.TimeStampedModel):
post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='comments')
class Like(news_models.TimeStampedModel):
comment = models.ForeignKey(Comment, null=True, on_delete=models.CASCADE, related_name='likes')
class Channel(models.Model):
name = models.CharField(max_length=100, blank=False, unique=True)
users = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name='channels')
posts = models.ManyToManyField(Post, related_name='channels')

Counting and filtering objects in a database with Django

I'm struggling a little to work out how to follow the relation and count fields of objects.
In my Django site, I have a profile model:
user = models.ForeignKey(User, unique=True)
name = models.CharField(_('name'), null=True, blank=True)
about = models.TextField(_('about'), null=True, blank=True)
location = models.CharField(_('location'), null=True, blank=True)
website = models.URLField(_('website'), null=True, blank=True)
My understanding is that this is using the username as the foreign key.
I would like to be able to count and display the number of completed profiles my users have filled out, and ones that have a specific "element / field"? (name)* filled out. I tried:
Profile.objects.all().count()
That gave me the same number of profiles as users, which I am guessing is because the profile model exists for each user, even if it is blank.
I'm unsure how to count profiles that have one of these fields completed in them, and I am also unsure how to count the number of completed "name" fields that have been completed.
I tried:
Profile.objects.all().name.count()
Django has some good docs on queryset api, but its currently going a little over my head
please excuse my use of incorrect terminology.
You should be able to get them using:
Profile.objects.filter(name__isnull=False)

Categories

Resources