Display foreign key value in django template - python

I've looked through the similar questions and was unable to find a solution that fits or I'm missing something? I have two models(SafetyCourse and SafetyCourseTaken) I have a foreign key relationship that points from "safety courses taken" to safety course, shown below:
models.py
class SafetyCourse(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
name = models.CharField(max_length=128, unique=True)
def __str__(self):
return self.name
class SafetyCoursesTaken(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
profile = models.ForeignKey(EmployeeProfile, on_delete=models.CASCADE)
course = models.ForeignKey(SafetyCourse, on_delete=models.CASCADE, related_name='course_name')
conducted_date = models.DateTimeField(null=True, blank=True)
expiration_date = models.DateTimeField(null=True, blank=True)
class Meta:
verbose_name_plural = 'Safety Courses Taken'
views.py
class ManageSafetyCourseTakenView(LoginRequiredMixin, generic.ListView):
login_url = reverse_lazy('users:login')
model = SafetyCoursesTaken
template_name = 'ppm/courses-taken.html'
paginate_by = 10
# override get_queryset to only show training related to employee profile
def get_queryset(self):
pk = self.kwargs['pk']
return SafetyCoursesTaken.objects.filter(profile_id=pk)
course-taken.html(template)
{% for course_taken in object_list %}
<tr>
<td>{{ course_taken.course_id}}</td>
</tr>
{% endfor %}
I've tried a number of solutions to similar questions but was unable to find a correct one. I've tried: course_taken.course_name_set.select_related, course_taken.course_name_set, and a few others. What I want to do is just display the name of the course instead of the course id. What am I doing wrong?

Looking at your schema, I think it should be this in the template:
{% for course_taken in object_list %}
<tr>
<td>{{ course_taken.course.name }}</td>
</tr>
{% endfor %}

Related

Django return a ManyToMany field from other class in HTML

I have two classes in django:
class MovementsGyn(models.Model):
gyn_name = models.CharField('Name', max_length=70)
gyn_desc = models.TextField('Description', blank=True, null=True)
owner = models.ForeignKey(User, on_delete=models.CASCADE)
class Meta:
ordering = ['id']
class Rod(models.Model):
Rod_name = models.CharField('Rod Name', max_length=70)
movements_gym = models.ManyToManyField(MovementsGyn)
owner = models.ForeignKey(User, on_delete=models.CASCADE)
class Meta:
ordering = ['id']
And a view to show the result grouped:
def estatistica(request):
template = 'moviment.html'
estatic_movem_gyn = Rod.objects.filter(owner=request.user) \
.values('movements_gym__gyn_name').order_by('movements_gym__gyn_name') \
.annotate(qtde=Count('id'))
context = {
'estatic_movem_gyn' : estatic_movem_gyn
}
return render(request, template_name, context)
The result, in Postgress, is gyn_name grouped and, in qtde, the quantity of register that we have in database.
But i'm havving problema to show it in HTML:
{% for estatic_movem_gyn in estatic_movem_gyn %}
<tr>
<td>{{ estatic_movem_gyn.gyn_name }}</td>
<td>{{ estatic_movem_gyn.qtde }}</td>
</tr>
{% endfor %}
The qtde appears but HTML doesn't show gyn_name.

How to refrence to an item in WishList for a Product in Django?

I want to implement a wishlist for the products in my Django site so that I can represent them in a wishlist page to the user.
the products are in the products app.
products.models.py
class ControlValves(models.Model):
title = models.CharField(max_length=50, unique=True)
product_name = models.CharField(max_length=50, blank=True)
....
class Accessories(models.Model):
title = models.CharField(max_length=50, unique=True)
description = models.CharField(max_length=50, blank=True)
....
There is a services app that contains various services(models).
Then I want to create a wishlist in users app.
users.models.py
class Wishlist(models.Model):
owner = models.ForeignKey( User, on_delete=models.CASCADE)
title = models.CharField(max_length=50, null=True, blank=True)
item = models.ForeignKey( which_model_should_be_here??? , on_delete=models.CASCADE)
since I am fetching the list of products and services from two different apps and within each, there are various models:
question: 1- I don't know how to point to the selected product or service? should I declare a foreign key to each possible product model o services model, or there is another efficient way?
2- an example of how to load them to show to the user( i.e. how to write a query to load them from DB) would be great.
I also checked the answer to this and this, but they are fetching products from just one model, so it's easy because there should be just one foreign key.
I think a simple ManyToMany relation should work here. For example:
class Wishlist(models.Model):
owner = models.ForeignKey(User, on_delete=models.CASCADE)
title = models.CharField(max_length=50, null=True, blank=True)
accessories = models.ManyToManyField(Accessories)
services = models.ManyToManyField(ControlValves)
And to show them in template, you can simply use:
{% if user.is_authenticated %}
{% for wish in user.wishlist_set.all %}
{{ wish.title }}
{% for accessory in wish.accessories.all %}
{{ accessory.title }}
{% endfor %}
{% for service in wish.services.all %}
{{ service.title }}
{% endfor %}
{% endfor %}
{% endif %}
Update based on comments
If you have 10 model classes which can be added to the WishList model, then above approach won't work. Consider using the following:
class Wishlist(models.Model):
owner = models.ForeignKey(User, on_delete=models.CASCADE)
title = models.CharField(max_length=50, null=True, blank=True)
class WishListItem(models.Model):
wishlist = models.ForeignKey(WishList, on_delete=models.DO_NOTHING, related_name='wishitems')
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
content_object = generic.GenericForeignKey('content_type', 'object_id')
Reson for this is that it is not practical to have 10 m2m relation. Instead using GenericForeginKey to add any of the models you want to add to the WishListItem instance.
Now if you want to display them in template, then use the following code:
{% if user.is_authenticated %}
{% for wish in user.wishlist_set.all %}
{{ wish.title }}
{% for wishitem in wish.wishitems.all %}
{{ wishitem.content_object }}
{% endfor %}
{% endfor %}
{% endif %}
FYI, reason for M2M or adding extra model for items is that user can have multiple wishlists, so it is better to hold them in on DB table, and items in different.
This is just but my suggestion:
create a list of types which represent product model
types=((0, "ControlValves"),(1, "Accessories"))
class Wishlist(models.Model):
owner = models.ForeignKey( User, on_delete=models.CASCADE)
item_id = models.IntegerField()
item_type = models.IntegerField(choices=types)
Then on your views.py
def get_wishlist(request):
allList = models.Wishlist.objects.filter(ownder=ownder_id)
items = []
for listItem in allList:
if listItem.item_type==0:
product = models.ControlValves.objects.get(pk=listItem.item_id)
item = {"id": listItem.id, "title": product.title, ...}
items.append(item)
elif listItem.item_type==0:
product = models.Accessories.objects.get(pk=listItem.item_id)
item = {"id": listItem.id, "title": product.title, ...}
items.append(item)
return HttpResponse(items)

Django tree query spanning multi model relation

Please consider code the following code. I'd like to create something like a tree structure (it will be in a table) related to a specific loged-in user. I'd like to have an overviewpage in which all categories are shown for which this user has items in the subcategories. My query works, but gives me all subcategory records and all posible items in those subcategories (so not just the subset for which the user has records.
I have another way working by starting with the itemmodel and then going up in the tree, but thats not what i'm looking for (this makes creating a dynamic set of tables far to depended on the django template layer).
I've looked at select_related and prefetch, but I can't get close to a solution. Any help would be appriciated.
models.py:
from django.db import models
from model_utils.models import TimeStampedModel
from django.conf import settings
User = settings.AUTH_USER_MODEL
class MainCat(TimeStampedModel):
name = models.CharField(max_length=100, unique=True)
rank = models.IntegerField(default=10)
icon_class = models.CharField(max_length=100, null=True, blank=True)
class SubCat(TimeStampedModel):
name = models.CharField(max_length=100, null=False, blank=False)
slug = models.SlugField(null=True, blank=True)
icon_class = models.CharField(max_length=100, null=True, blank=True)
main_cat = models.ForeignKey(MainCat)
class Item(TimeStampedModel):
user = models.ForeignKey(User, blank=True, null=True)
item_name = models.CharField(max_length=100, null=False, blank=False)
sub_cat = models.ForeignKey(SubCat, blank=True, null=True)
views.py:
from django.views.generic import ListView
from django.contrib.auth.mixins import LoginRequiredMixin
from .models import MainCat
class MainCatByUserListView(LoginRequiredMixin, ListView):
model = MainCat
def get_queryset(self):
qs = super(MainCatByUserListView, self).get_queryset()
qs = qs.filter(subcat__item__user=self.request.user)
return qs
template:
< html >
< body >
{% for maincat in object_list %}
< ul >
<li> {{maincat.name}} </li>
<ul>
{% for subcat in maincat.subcat_set.all %}
<li> {{subcat.name}} </li>
{% for item in subcat.item_set.all %}
<li> {{item.name}} </li>
</ul>
</ul>
{% endfor %}
{% endfor %}
{% endfor %}
< / body >
< / html >
{% endfor %}
You should be able to use something like: Subcat.objects.filter(item_set__user=self.request.user).select_related('main_cat')
Finaly got to an answer to my question. For future reference:
class MainCatListView(LoginRequiredMixin, ListView):
model = MainCat
template_name = 'app/main_cat_overview.html'
def get_queryset(self):
qs = super(MainCatListView, self).get_queryset()
qs_user_cat_set = SubCat.objects.filter(item__user=self.request.user).prefetch_related(Prefetch(
"item_set",
queryset=Item.objects.filter(user=self.request.user),
to_attr="item_attr")
).distinct()
qs = qs.filter(subcat__item__user=self.request.user).prefetch_related(Prefetch(
"subcat_set",
queryset=qs_user_subcat_set,
to_attr="subcat_attr")
).distinct()
return qs

How can I insert data in two different models?

I'm newbie in coding, and I'm trying my first Django app.
This time I have three different models, but with a single form at the momment when I hit Save I want to save data on that form model and in the others 2 models.
So in my display I want to loop the other two models to show what I have.
Is that even possible?
models.py
class Personame(models.Model):
name = models.CharField(max_length=128)
def __str__(self):
return self.name
class Personlastname(models.Model):
last_name = models.CharField(max_length=128)
def __str__(self):
return self.last_name
class Personinfo(models.Model):
personame = models.CharField(max_length=128)
personlastname = models.CharField(max_length=128)
address = models.TextField()
phone_number = models.CharField(max_length=128)
hobbies =models.CharField(max_length=128)
def __str__(self):
return self.personame
forms.py:
class personform(forms.ModelForm):
personame = forms.CharField(label = "Name")
personlastname = forms.CharField(label = "Last Name")
class Meta:
model = Personinfo
fields = ["personame","personlastname","address","phone_number","hobbies"]
views.py:
def index(request):
queryset = Personame.objects.all()
queryset2 = Personlastname.objects.all()
qs = chain(queryset,queryset2)
form = personform(request.POST or None)
context = {
"qs": qs,
"form":form,
}
if form.is_valid():
instance = form.save()
return render(request, "index.html", context)
index.html:
<form method="POST" action="">{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Save!" />
</form>
<table >
<tr>
<th>Name</th>
<th>Last Name</th>
</tr>
{% for item in qs %}
<tr>
<td>{{ item.name }}</td>
<td>{{ item.last_name }}</td>
</tr>
{% endfor %}
</table>
Basically I want to save name in Personinfo and Personame, and I want to save last_name in Personinfo and Personlastname. So I can show Personame and Personlastname in template.
Can anyone help me please?
I would be very happy for your help... Thanks
Well your models don't make any sense at all. They really should be one model. you have not defined any relationship between any of the models. To do that you will have to add a OneToOneField or a ForeignKey. That effectively means you are having an extra column for each item of data. Totally redundant.
class Personinfo(models.Model):
name = models.CharField(max_length=128)
last_name = models.CharField(max_length=128)
address = models.TextField()
phone_number = models.CharField(max_length=128)
hobbies =models.CharField(max_length=128)
def __str__(self):
return self.personame
This makes your life so much easier with simpler coding.
your models don't have class Meta , need to define the table name in class meta like :
class Meta:
managed = True
db_table = 'tableName'
Then u need to override save function in personform

Django Multiple ForeignKey Navigation

I'm building a shopping cart. In my shopping cart an item can be composed of other items. I need to display a set of items with their corresponding associated parts in a single template. I know how to show a single item with its corresponding parts in a template, but I can't seem to figure out how to show more than one item, each with its own list of included parts.
I have fiddled with every permutation of tags in the template file:
# checkout.html
{% for item in cart_items %}
<tr>
<td class="left">
{{ item.name }}
<ul>
{% for part in item.product.buildpart.part_set.all %}
<li>{{ part.name }}
{% endfor %}
</ul>
</td>
<td>${{ item.price }}</td>
<td>{{ item.quantity }}</td>
<td class="right">${{ item.lineItemTotal }}</td>
</tr>
{% endfor %}
Here is the vew that generates the template:
# views.py
def checkout(request):
cart_items = get_cart_items(request)
<snip>
return render(request, 'checkout.html', locals())
And here's the get_cart_items() function that returns all the items in the user's shopping cart:
# cart.py
def get_cart_items(request):
""" return all items from the current user's cart """
return CartItem.objects.filter(cart_id=get_cart_id(request))
Here's the CartItem model:
# models.py
class Item(models.Model):
cart_id = models.CharField(max_length=50)
quantity = models.IntegerField(default=1)
product = models.ForeignKey(PartModel, unique=False)
class Meta:
abstract = True
<snip>
class CartItem(Item):
date_added = models.DateTimeField(auto_now_add=True)
class Meta:
ordering = ['date_added']
verbose_name = "Cart Item"
<snip>
The 'product' field is a ForeignKey to the PartModel model:
# models.py
class PartModel(models.Model):
family = models.ForeignKey(PartFamily)
name = models.CharField("Model Name", max_length=50, unique=True)
slug = models.SlugField(help_text="http://www.Knowele.com/<b>*slug*</b>",
unique=True)
<snip>
buildpart = models.ManyToManyField('self', through='BuildPart',
symmetrical=False, related_name='+')
class Meta:
ordering = ['name']
verbose_name = "Product Model"
<snip>
The PartModel model has a ManyToMany relationship with itself through the buildpart field and the BuildPart model to facilitate the notion of catalog items that can be composed of other catalog items:
# models.py
class Build(models.Model):
build = models.ForeignKey(PartModel, related_name='+')
part = models.ForeignKey(PartModel, related_name='+')
quantity = models.PositiveSmallIntegerField(default=1)
class Meta:
abstract = True
unique_together = ('build', 'part')
def __unicode__(self):
return self.build.name + ' with ' + str(self.quantity) + ' * ' + \
self.part.family.make.name + ' ' + self.part.name
class BuildPart(Build):
pass
class Meta:
verbose_name = "Build Part"
I can't seem to make the necessary ForeignKey traversals in the template (listed above) in order to get all the parts associated with the user's items in the CartItem model. Is it something I'm not doing right in the template or am I not packaging up the right QuerySets in my view?
The second part of this issue is that once I get those parts, I need them to show up in the order specified in the 'order' integer field of the PartType model:
# models.py
class PartType(models.Model):
name = models.CharField("Part Type", max_length=30, unique=True)
slug = models.SlugField(unique=True)
order = models.PositiveSmallIntegerField()
description = models.TextField(blank=True, null=True)
class Meta:
ordering = ['name']
verbose_name = "Product Type"
def __unicode__(self):
return self.name
class PartFamily(models.Model):
make = models.ForeignKey(PartMake)
type = models.ForeignKey(PartType)
name = models.CharField("Family Name", max_length=30,
unique=True)
slug = models.SlugField(unique=True)
url = models.URLField("URL", blank=True, null=True)
description = models.TextField(blank=True, null=True)
class Meta:
ordering = ['name']
verbose_name = "Product Family"
verbose_name_plural = "Product Families"
def __unicode__(self):
return self.name
So as you can see, in the PartModel model, the 'family' field is a ForeignKey to the PartFamily model, and in the PartFamily model the 'type' field is a ForeignKey to the PartType model, within which is the all-important 'order' field that the parts need to be ordered by.
I hope this makes sense and you can see why this is so complicated for a noob like me.
Just iterate on item.product.buildpart.all:
{% for item in cart_items %}
[...]
{% for part in item.product.buildpart.all %}
{{ part.name }}[...]
{% endfor %}
{% endfor %}

Categories