combining two or more querysets from different models in django - django

Main model:
class MainCategory(models.Model):
title = models.CharField(max_length=120, unique=True)
App#1:
class Category(models.Model):
title = models.CharField(max_length=120, unique=True)
main_category = models.ForeignKey(MainCategory, default=1, related_name='car_category')
App#2:
class Category(models.Model):
title = models.CharField(max_length=120, unique=True)
main_category = models.ForeignKey(MainCategory, default=1, related_name='classifieds_category')
on home page I want a combined list of both category list items as follows.
{% for object in main_cat_list %}
{{ object.title }}
{% for item in object.car_category %}
{{ item.title }}
{% endfor %}
{% endfor %}
How I can insert classifieds category also inside this list?

If you merely want to also display the classified_category as you have the car_category.
{% for object in main_cat_list %}
{{ object.title }}
{% for item in object.car_category %}
{{ item.title }}
{% endfor %}
{% for item in object.classified_category %}
{{ item.title }}
{% endfor %}
{% endfor %}

Related

Django - Problem with DB query using foreign key

I'm using Django for a Web app and I have the following data model:
class classi(models.Model):
nome = models.TextField(null=True)
class Meta:
db_table = 'classi'
class users(models.Model):
name = models.TextField(null=True)
email = models.TextField(null=True)
password = models.TextField(null=True)
classe = models.ForeignKey(classi, db_column='classe', on_delete=models.CASCADE, null=True)
class Meta:
db_table = 'users'
class smartphone(models.Model):
marca = models.TextField(null=True)
modello = models.TextField(null=True)
possessore = models.ForeignKey(users, db_column='possessore', on_delete=models.CASCADE, null=True)
class Meta:
db_table = 'smartphone'
My goal is to show, on an HTML page, all classi, and for each classi all users and for each user all smartphone.
How can I implement my view.py and my html file?
The only solution that I found is to scan all table with a for loop and, through a condition, select the row using foreign key:
{% for c in classi %}
<p>{{ c.nome }}</p>
{% for u in users %}
{% if u.classe == c %}
<p>{{ u.name }}, {{ u.email }}, {{ u.password }}</p>
{% for s in smartphone %}
{% if s.possessore == u %}<p>{{ s.marca }}, {{ s.modello }}</p> {% endif %}
{% endfor %}
{% endif %}
{% endfor %}
{% endfor %}
Is there a better solution?
You could use backwards relations, which will only have items that have a connection
The general format is obj.{model}_set but you can also set it to something different in the models.py with the related_name attr in the ForeignKey field
{% for c in classi %}
<p>{{ c.nome }}</p>
{% for u in c.users_set.all %}
<p>{{ u.name }}, {{ u.email }}, {{ u.password }}</p>
{% for s in u.smartphone_set.all %}
<p>{{ s.marca }}, {{ s.modello }}</p>
{% endfor %}
{% endfor %}
{% endfor %}
Or, and this is probably cleaner:
Go the reverse way by looping through the smartphones in the top and just order smartphones by nome in the view with smartphoneList = smartphone.objects.all().order_by('possessore__classe__nome') so they are grouped together
{% for s in smartphoneList %}
<p>{{ s.possessore.classe.nome }}</p>
<p>{{ s.possessore.name }}, {{ s.possessore.email }}, {{ s.possessore.password }}</p>
<p>{{ s.marca }}, {{ s.modello }}</p>
{% endfor %}
Note after writing this I noticed #Lucas Grugru as already posted the reverse relations way.. From my testing it doesn't require pre-fetching, but it's probably a good idea to do that (I also have no idea). I'm still posting this because I think looping through smartphones might be a cleaner way of doing it
You can use *prefetch_related for prefetching related object from foreign key. More information: https://docs.djangoproject.com/fr/4.1/ref/models/querysets/#prefetch-related
The view:
def view(request):
classe = Classi.objects.all().prefetch_related("users_set").prefetch_related("users_set__smartphone_set")
context = {}
context["classe"] =) classe
return render(request, 'template.html', context)
And the html:
{% for c in classe %}
<p>{{ c.nome }}</p>
{% for u in c.users_set.all %}
<p>{{ u.name }}, {{ u.email }}, {{ u.password }}</p>
{% for s in u.smartphone_set.all %}
<p>{{ s.marca }}, {{ s.modello }}</p>
{% endfor %}
{% endfor %}
{% endfor %}

Django - how to get all the users in team when using a costumised user model

I am new to django and have a question: I created a CustomUser model within a users app.
I tried
from users.models import CustomUser, Team
team1= Team.objects.first()
users_team1= team1.user.objects.all()
and it doesnt get me the list of users in this Team
class CustomUser(AbstractUser):
bio= models.CharField(max_length=300, null= True, blank=True)
class Team (models.Model):
title = models.CharField(max_length=200)
user= models.ManyToManyField(get_user_model())
date_created= models.DateTimeField(auto_now_add=True, blank=True, null=True)
date_updated= models.DateTimeField(auto_now=True,blank=True, null=True )
def __str__(self):
return self.title
def get_absolute_url(self): # new
return reverse('team_detail', args=[str(self.pk)])
I want created a HTML page
{% extends '_base.html' %}
{% block title %}{{ object.title }}{% endblock title %}
{% block content %}
<div class="team-detail">
<h2>{{ team.title }}</h2>
<p>Team tile : {{ team.title }}</p>
<p>user: {{ team.user }}</p>
</div>
{% endblock content %}
how can i show all the users in a specific Team?
Thanks in advance.
You should do:
from users.models import CustomUser, Team
team1= Team.objects.first()
# lets pass team1 to your template
return render(request, 'template/name.html', {'team': team1})
Your template should be sthg like:
{% extends '_base.html' %}
{% block title %}{{ object.title }}{% endblock title %}
{% block content %}
<div class="team-detail">
<h2>{{ team.title }}</h2>
<p>Team tile : {{ team.title }}</p>
{% for user in team.user.all %}
<p>user: {{ user }}</p>
{% endfor %}
</div>
{% endblock content %}

Django Fetching Data From DataBase Based on join Using ORM

I want to join two models as shown below and the join should be Harsha to Bank only(not Bank to Harsha)
model.py
class Harsha(models.Model):
name = models.CharField(max_length=255)
email = models.CharField(max_length=255)
class Bank(models.Model):
user = models.ForeignKey(Harsha, on_delete=models.CASCADE)
accountnumber = models.BigIntegerField()
ifsc = models.CharField(max_length=255)
branch = models.CharField(max_length=255)
bank = models.CharField(max_length=255)
views.py
test = Harsha.objects.all()
test1 = Bank.objects.all() # its working for me but i want join from Harsha table
in templates
# I want this
{% for tes in test %}
{{ tes.name }}
{{ tes.email }}
{{ tes.bank.accountnumber }} # how can I get this field
{{ tes.bank.ifsc }} # how can I get this field
{% endfor %}
# its working
{% for tes in test1 %}
{{ tes.user.name }}
{{ tes.user.email }}
{{ tes.accountnumber }}
{{ tes.ifsc }}
{% endfor %}
You can get it like this(using reverse relationship):
{% for tes in test %}
{{ tes.name }}
{{ tes.email }}
{% for bank in tes.bank_set.all %}
{{ bank.accountnumber }}
{{ bank.ifsc }}
{% endfor %}
{% endfor %}

Using MPTT do get_children in templates (at runtime)

my template receives a variable called categories, and I want to list the categories that are "sons" of its father categories
this is my code in template
{% for category,structure in categories|tree_info %}
{% if structure.new_level %}
<li>{{ category.name }} </li>
{% endif %}
{% for level in structure.closed_levels %}
<li>{{level.name}}
{% endfor %}
<ul class="noJS">
{% for cat in category.get_children|tree_info %}
<li>{{ cat.name }}aa </li>
{% endfor %}
</ul>
{% endfor %}
this is the model
class Category(MPTTModel):
name = models.CharField(max_length=50, unique=True)
description = models.TextField(blank=True)
parent = TreeForeignKey('self', null=True, blank=True, related_name='children')
class MPTTMeta:
order_insertion_by = ['name']
def __unicode__(self):
return self.name
any idea?
This worked
{% for category in categories %}
<li>
{{ category.name }}
<ul class="noJS">
{% for cat in category.get_children %}
<li>{{ cat.name }} </li>
{% endfor %}
</ul>
</li>
{% endfor %}

ForeignKey. How to get data?

class Property(models.Model):
title = models.CharField(max_length=255)
class CurrentPrice(models.Model):
current = models.ForeignKey(Current)
prop = models.ForeignKey(Property)
price = models.DecimalField(max_digits=5, decimal_places=2)
class Current(models.Model):
name = models.CharField(max_length=20)
views.py:
...
p = Property.objects.all()
return render_to_response('index.html',{'p':p},context_instance=RequestContext(request))
How to get price of Property and display it in my template?
template:
{% for item in p %}
{{ item.title }}
{{ item.price }} # ???
{% endfor %}
I'm not sure what is your purpose/design of models, which doesn't look appropriate from what you have shown.
You will have many CurrentPrice per Property object, so in template you can do is
{% for item in p %}
{{ item.title }}
{% for cp in item.currentprice_set.all %}
{{ cp.price }}
{% endfor %}
{% endfor %}
If Property can have multiple CurrentPrice objects (what is by default):
{% for item in p %}
{{ item.title }}
{% for current_price in item.currentprice_set.all %}
{{ current_price.price }}
{% endofor %}
{% endfor %}
If only one (but in that case it is better to use o2o field instead of the FK fiel else it is up on you to prevent multiple CurrentPrice records pointing to the same Property):
{% for item in p %}
{{ item.title }}
{{ item.currentprice_set.get.price }}
{% endfor %}
I think what you're trying to do is something like that below.
class Property(models.Model):
title = models.CharField(max_length=255)
#property
def current_price(self):
# The current price is the last price that was given.
if self.pricing_history.count() > 0:
return self.pricing_history.order_by('-when')[0].amount
return None
class Price(models.Model):
prop = models.ForeignKey(Property, related_name='pricing_history')
amount = models.DecimalField(max_digits=5, decimal_places=2)
when = models.DateTimeField(auto_now_add=True)
example in template:
{% for item in p %}
{{ item.title }}
{{ item.current_price }}
{% endfor %}