I can't get the cat name and kitten type from the Cat and Kitten models into the template.
This is my model.py
class Cat(models.Model):
cat_name = models.CharField(max_length=200)
def __str__(self):
return self.cat_name
class Kitten(models.Model):
cat = models.ForeignKey(Cat, on_delete=models.CASCADE, related_name='kittens')
kitten_type = models.CharField(max_length=200)
def __str__(self):
return self.kitten_type
My views.py
class CatViews(generic.ListView):
model = Cat
template_name = 'polls/cats.html'
class CatDetail(generic.DetailView):
model = Kitten
template_name = 'polls/kitten.html'
My urls.py
urlpatterns = [
path('cats/', views.CatViews.as_view(), name='catlist'),
path('cats/<int:pk>/', views.CatDetail.as_view(), name='catdetail'),
]
And finally, polls/kitten.html
<h3>{{cat.cat_name}}</h3>
{% for kitty in cat.kittens.all %}
<p>{{ kitty.kitten_type }}</p>
{% endfor %}
The url is working, I'm just not able to display the fields from the models into their respective html elements. What am I missing?
Figured it out. I had to set the CatDetailView to the Cat model, not Kitten model.
The final code:
class CatDetail(generic.DetailView):
model = Cat
template_name = 'polls/kitten.html'
class CatViews(generic.ListView):
model = Cat
template_name = 'polls/cats.html'
context_object_name='cat'
And your polls/cats.html would be like,
<h3>{{cat.cat_name}}</h3>
{% for kitty in cat.kittens.all %}
<p>{{ kitty.kitten_type }}</p>
{% endfor %}
Alter you views.py with the following
class CatViews(generic.ListView):
model = Cat
context_object_name = 'cat'
template_name = 'polls/cats.html'
Alter your polls/kitten.html
<h3>{{cat.cat_name}}</h3>
{% for kitty in cat.kittens.all %}
<p>{{ kitty.kitten_type }}</p>
{% endfor %}
EDIT
Additionally, alter you CatDetail
class CatDetail(generic.DetailView):
model = Kitten
context_object_name = 'kittens'
template_name = 'polls/kitten.html'
EDIT 2
Alter your polls/kitten.html to this.
<h3>{{cat.cat_name}}</h3>
{% for kitty in cat.catdetail.all %}
<p>{{ kitty.kitten_type }}</p>
{% endfor %}
Related
How can I render the data in from the model to the html? The way they describe it in the docs doesn´t work for me. Here is what I have:
class Thema(models.Model):
title = models.CharField(max_length=70, help_text="The title of the Post")
publication_date = models.DateField(verbose_name="Date the Post was published.")
text = models.TextField(max_length=5000,default='kein Textinhalt vorahnden')
category = models.ForeignKey(Category, on_delete=models.CASCADE)
bilder = models.ForeignKey(Bilder, on_delete=models.CASCADE)
links = models.ManyToManyField(Link)
files = models.ManyToManyField(File)
tags = models.ManyToManyField(Tag)
def __str__(self):
return self.title
The View:
from .models import Thema
from django.views.generic import TemplateView
class HomePageView(TemplateView):
model = Thema
context_object_name = 'themas'
template_name = "home/home.html"
And the template:
<h2>THEMAS</h2>
<ul>
{% for thema in themas %}
<li>{{ thema.title }}</li>
{% endfor %}
</ul>
How can I render the many to many fields?
thanks for answers
Your template assumes that themas is a list. But themas is actually only one model instance of Thema.
class HomePageView(TemplateView):
model = Thema # model is Thema
context_object_name = 'thema' # 'themas' is missleading --> change to 'thema'
# because this view only passes ONE Thema to the view
template_name = "home/home.html"
<h1>Thema: {{ thema.title }}</h1>
<h3>Links:</h3>
{% for link in thema.links.all %}
<li>{{ link }}</li>
{% endfor %}
<h3>Tags:</h3>
{% for tag in thema.tags.all %}
<li>{{ tag }}</li>
{% endfor %}
i am trying to add objects from my model into my CBV, i have a model created so i am trying to pass them to my views, but its not working,tho i have 2 classes created which are Pricing and Pricingservice, i want an inline for a field in Pricingservice which i did, but i dont know how to add both to my view in CBV in the view so as to access them in my template, here is my code below, kindly help me out because i have been battling with this for days, thanks
model.py
class Pricing(models.Model):
plans = models.CharField(max_length=250)
amount = models.CharField(max_length=250)
services = models.CharField(max_length=250)
def __str__(self):
return self.plans
class Pricingservice(models.Model):
pricing = models.ForeignKey(Pricing, default=None, on_delete=models.CASCADE)
services = models.CharField(max_length=250)
def __str__(self):
return self.pricing.plans
admin.py
class PricingserviceAdmin(admin.StackedInline):
model = Pricingservice
#admin.register(Pricing)
class PricingAdmin(admin.ModelAdmin):
inlines = [PricingserviceAdmin]
class Meta:
model = Pricing
views.py
class HomePageView(TemplateView):
template_name = 'pages/home.html'
def get_context_data(self, **kwargs):
context = super(HomePageView, self).get_context_data(**kwargs)
context['Pricing'] = Pricing.objects.all()
return context
template.html
<div class="row">
{% for p in Pricing %}
<div class="col-md-3 ftco-animate">
<div class="pricing-entry pb-5 text-center">
<div>
<h3 class="mb-4">{{ p.plans }}</h3>
<p><span class="price">#{{ p.amount }}</span> <span class="per">/ Month</span></p>
</div>
<ul>
<li>{{ p.services }}</li>
</ul>
<p class="button text-center">Get Offer</p>
</div>
</div>
{% endfor %}
</div>
[] 1
Try this solution:
class HomePageView(ListView):
model = Pricing
template_name = 'pages/home.html'
And then try this template:
{% for pricing in object_list %}
{{pricing.plans}}<br>
{% for service in pricing.pricingservice_set.all %}
{{ service.services }}<br>
{% endfor %}
{% endfor %}
Please add some styling yourself. :)
It would be better to use a ListView. You would need to tell Django what the relevant model for your view is, i.e.:
class HomePageView(ListView):
model = Pricingservice
template_name = 'pages/home.html'
And then in your template, you can use:
{% for pricingservice in pricingservice_list %}
{{ pricingservice.pricing }}
{% endfor %}
I am not sure exactly how your two models differ, but maybe it would be better to merge them?
try this
views.py
class HomePageView(TemplateView):
template_name = 'pages/home.html'
def get_context_data(self, **kwargs):
context = super(HomePageView, self).get_context_data(**kwargs)
context['Pricing'] = Pricing.objects.all()
return context
class PricePageView(ListView):
model = Pricingservice
template_name = 'pages/home.html'
urls.py
path('', HomePageView.as_view(), name='home'),
path('price/', PricePageView.as_view(), name='price'),
template.html
{% for pricingservice in Pricingservice_list %}
<ul>
<li>{{ pricingservice }}</li>
</ul>
{% endfor %}
am not sure this will work but try this if that answer does not work for you
I am working on a django project and I have 2 models that look like this:
class Playlist(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL,on_delete=models.CASCADE,related_name='playlist_user')
name = models.CharField(max_length=120)
image = models.ImageField(upload_to=upload_image_path)
genre = models.CharField(max_length=120,null=True,blank=True)
track = models.ManyToManyField('Post',related_name='playlist_track')
class Post(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL,on_delete=models.CASCADE)
title = models.CharField(max_length=120)
slug = models.SlugField(unique=True)
image = models.ImageField(upload_to=upload_image_path)
audiofile = models.FileField(upload_to=upload_image_path,null=True)
genre = models.CharField(max_length=120,null=True,blank=True)
and this view:
def userprofileview(request):
own_tracks = Post.objects.filter(user=request.user)
playlist_ = Playlist.objects.filter(user=request.user)
context = {
'own_tracks':own_tracks,
'playlist_':playlist_
}
return render(request,'userprofile.html',context)
but when I try to query the posts from the playlist like this:
{% for object in playlist_ %}
{{ object.track }}
{% endfor %}
I get:
posts.Post.None
Thank you for any suggestions
In order to access the related objects, you need to add .all at the end:
{% for object in playlist_ %}
{% for post in object.track.all %}
{{ post.title }}
{% endfor %}
{% endfor %}
To avoid the N+1 problem, you can use .prefetch_related(..) [Django-doc]:
def userprofileview(request):
own_tracks = Post.objects.filter(user=request.user)
playlist_ = Playlist.objects.filter(user=request.user).prefetch_related('post')
context = {
'own_tracks':own_tracks,
'playlist_':playlist_
}
return render(request,'userprofile.html',context)
i am creating an website where a user can search for recipes by their ingredients. I wish that when a user finally see recipe, ingredients there would be splited with ', ' in view. for now it is just space. I tried to do this in my model, but they i get error as in title
- 'CharField' object has no attribute split.
Models:
from django.db import models
class Ingredient(models.Model):
ingredient_name = models.CharField(max_length=250)
igredient_name1 = ingredient_name.split(', ')
def __str__(self):
return self.ingredient_name1
class Recipe(models.Model):
recipe_name = models.CharField(max_length=250)
preparation = models.CharField(max_length=1000)
ingredients = models.ManyToManyField(Ingredient)
def __str__(self):
return self.recipe_name
template:
<div>
<h1>Drink drank drunk</h1>
</div>
{% for drink in results %}
<div>
<p>{{ drink.recipe_name }}</p>
<p>Preparation: {{ drink.preparation }}</p>
<p>Ingredients:
{% for ingredient in drink.ingredients.all %}
{{ingredient.ingredient_name}}
{% endfor %}
</p>
</div>
{% endfor %}
view:
def drink_list(request):
template = "drinks/drink_list.html"
return render(request, template)
def search_results(besos):
query = besos.GET.get('q')
q = Q()
for queries in query.split(', '):
q |= (Q(ingredients__ingredient_name__icontains=queries))
results = Recipe.objects.filter(q)
template = "drinks/search_results.html"
context = {
'results' : results,
}
return render(besos, template, context)
After some mess understanding what is needed to accomplish it seems that the solution is just to add the desired comma into the template, modifying the forloop as follows:
{% for ingredient in drink.ingredients.all %}}
{{ingredient.ingredient_name}}{% if not forloop.last %},{% endif %}
{% endfor %}
I'm working on multi-user rss reader. I want to limit display of posts only to those which are unread. I've managed to do this in my single "feed" view as below, but I can't figure out how to do the same in multiple feed aka "category" view.
I've been trying something like here https://docs.djangoproject.com/en/1.5/topics/db/queries/#spanning-multi-valued-relationships but it didn't work for me
Should I change my "category" view code or template code? and if so how would you go about it?
thanks!
-S
models
class UserCategory(models.Model):
name = models.CharField(unique=False, max_length=64)
user = models.ForeignKey(User)
slug = AutoSlugField(populate_from='name', always_update='True', unique_with='user')
class Feed(models.Model):
feed_url = models.URLField(unique=True)
default_title = models.CharField(max_length=64, blank=True)
link = models.URLField(blank=True)
class UserFeed(models.Model):
feed = models.ForeignKey(Feed)
title = models.CharField(max_length=64)
category = models.ForeignKey(UserCategory)
user = models.ForeignKey(User)
slug = AutoSlugField(populate_from='title', always_update='True', unique_with='user')
class Post(models.Model):
feed = models.ForeignKey(Feed)
title = models.CharField(max_length=256)
content = models.TextField()
link = models.URLField(max_length=512)
class ReadPost(models.Model):
user = models.ForeignKey(User)
post = models.ForeignKey(Post)
views
def feed(request, user_feed_slug):
user_feed = get_object_or_404(UserFeed.objects.filter(slug=user_feed_slug, user=request.user))
read_post = ReadPost.objects.filter(user=request.user).values_list('post')
posts = Post.objects.select_related().filter(feed=user_feed.feed).exclude(id__in=read_post)
def category(request, user_category_slug):
user_category = get_object_or_404(UserCategory.objects.filter(slug=user_category_slug, user=request.user))
templates
feed
{% for post in posts %}
{{ post.title }}
{% endfor %}
category
{% for feed in user_category.userfeed_set.all %}
{{ feed.title }}
{% for post in feed.feed.post_set.all %}
{{ post.title }}
{{ post.content }}
{% endfor %}
{% endfor %}
You can write custom template filter, i.e:
#register.filter
def unread(posts, read_posts):
return posts.exclude(id__in=read_posts)
(before you must pass read_post to category template context).
Try this queryset:
def category(request, user_category_slug):
user_category = get_object_or_404(UserCategory, slug=user_category_slug,
user=request.user))
feeds = UserFeed.objects.filter(category__slug=user_category_slug, user=request.user)\
.prefetch_related('feed__post_set')
then in your template:
{% for feed in feeds %}
{{ feed.title }}
{% for post in feed.feed.post_set.all %}
{{ post.title }}
{{ post.content }}
{% endfor %}
{% endfor %}