I'm new to Django and I'ma building a basic blog application.
I cant show manytomany field (in tags) and a foreignkey field (comments) in my details page.
models.py
class BlogContent(models.Model):
title = models.CharField(max_length=200)
author = models.CharField(max_length=200)
content = models.TextField()
date_published = models.DateField(auto_now=True)
image = models.ImageField(upload_to='media/')
def __str__(self):
return self.title
class TagName(models.Model):
tag = models.ManyToManyField(BlogContent, null=True)
name = models.CharField(max_length=100, blank=True, null=True)
def __str__(self):
return self.name
class Comment(models.Model):
comt_text = models.TextField()
comments = models.ForeignKey(BlogContent, on_delete=models.CASCADE)
date_published = models.DateField(auto_now=True)
name = models.CharField(max_length=200, blank=True, null=True)
def __str__(self):
return self.name
views.py
def details(request, blogcontent_id):
data_blog = get_object_or_404(BlogContent, pk=blogcontent_id)
data_tag = get_object_or_404(TagName, pk=blogcontent_id)
data_comment = Comment.objects.select_related()
return render(request, 'details.html',
{'data_blog': data_blog, 'data_tag':data_tag, 'data_comment':data_comment})
details.html
{% extends 'base.html' %}
{% block body_base %}
<img class="card-img-top img-responsive" src={{ data_blog.image.url }} alt="Card image cap">
<h2 class="blog-post-title">{{ data_blog.title }}</h2>
<p class="blog-post-meta">{{ data_blog.date_published }} {{ data_blog.author }}</p>
<p>{{ data_blog.content }}</p>
{% endblock %}
how do i show foreignkey and manaytomany fieds after this?
TBH this is much easier if you use class based views.
The view would simply be:
class BlogContentDetail (DetailView):
model = BlogContent
The url call would be url(r'^blog-detail/(?P<pk>\d+)/$, BlogContentDetail.as_view(), name="blog_detail")
Your html file should be called blogcontent_detail.html and held within the app subfolder in the templates folder
The template would then be:
{% extends 'base.html' %}
{% block body_base %}
<img class="card-img-top img-responsive" src={{ object.image.url }} alt="Card image cap">
<h2 class="blog-post-title">{{ object.title }}</h2>
<p class="blog-post-meta">{{ object.date_published }} {{ object.author }}</p>
<p>{{ object.content }}</p>
{% for tag in object.tags_set.all %}{{ tag }}{% endfor %}
{% endblock %}
You can iterate the ManyToMany Field in this way
{% for tags in data_tag.tag.all %}
<p > {{tags}} </ p>
{% endfor %}
For foreign key
{{data_comment.comments}}
Related
I have to do wishlist, I have done wishlist page, model and html.bBut when I click on the button bellow my post, I'm redirected to wishlist page and post didnt saved in my wishlist.So thats my code:
models.py
class Wishlist(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL,
on_delete=models.CASCADE)
wished_item = models.ForeignKey(Posts, on_delete=models.CASCADE)
def __str__(self):
return self.wished_item.title
class Posts(models.Model):
TYPE = Choices(
('private', _('private')),
('business', _('business')),
)
STATUS = Choices(
('active', _('active')),
('deactivated', _('deactivated'))
)
owner = models.ForeignKey(settings.AUTH_USER_MODEL, blank=True, null=True, related_name='posts',
on_delete=models.CASCADE, verbose_name='owner')
phone_number = PhoneNumberField(verbose_name=_('Phone_number'), null=False, blank=False, unique=True)
title = models.CharField(verbose_name=_('Title'), max_length=100)
text = RichTextField(verbose_name=_('Text'))
image = models.ImageField(upload_to='images/%Y/%m/%d/', null=True, blank=True, validators=[file_size])
price = models.DecimalField(verbose_name=_('Price'), decimal_places=2, max_digits=9)
status = models.CharField(choices=STATUS, max_length=50)
created = models.DateTimeField(auto_now=True)
type = models.CharField(choices=TYPE, max_length=50)
def __str__(self):
return self.title
views.py
class WishListView(generic.View):
def get(self, *args, **kwargs):
wish_items = Wishlist.objects.filter(user=self.request.user)
context = {
'wish_items': wish_items
}
return render(self.request, 'wishlist/wishlist.html', context=context)
def addToWishList(request):
if request.method == 'POST':
post_var_id = request.POST.get('object-id')
post_var = Posts.objects.get(id=post_var_id)
print(post_var)
try:
wish_item = Wishlist.objects.get(user=request.user, post=post_var)
if wish_item:
wish_item.save()
except:
Wishlist.objects.create(user=request.user, post=post_var)
finally:
return HttpResponseRedirect(reverse('wishlist'))
wishlist.html
{% extends 'posts/base.html' %}
{% load thumbnail %}
{% block content %}
<div>
{% for item in wish_items %}
{% if item.wished_item.image1 %}
<img src="{{item.wished_item.image.url}}" alt="">
{% endif %}
</div>
<div>
<li>{{item.wished_item.title}}</li>
<li>{{item.wished_item.text}}</li>
<li>{{item.wished_item.price}}</li>
<li>{{item.wished_item.phone_number}}</li>
{% if item.wished_item.image %}
<img src="{% thumbnail item.wished_item.image 200x200 crop %}" alt="" />
<p></p>
{% endif %}
</div>
{% endfor %}
{% endblock %}
urls.py
urlpatterns = [
path("wishlist/", WishListView.as_view(), name='wishlist'),
path("add-to-wishlist", addToWishList, name='add-to-wishlist'),
]
and all posts template with add to wishlist button.
<ul>
{% for object in object_list %}
<li>Owner: {{ object.owner }}</li>
<li>Phone: {{ object.phone_number }}</li>
<li>Title: {{ object.title }}</li>
<li>Text: {{ object.text }}</li>
<li>Type: {{ object.type }}</li>
<li>Price: {{ object.price }}</li>
<li>Date: {{ object.created }}</li>
<p>
{% if object.image %}
<img src="{% thumbnail object.image 200x200 crop %}" alt="" />
{% endif %}
</p>
<form action="{% url 'add-to-wishlist' %}" method="POST">
{%csrf_token%}
<input type="hidden" name="object-id" value="{{object.id}}">
<input type="submit" value="Add to Wishlist">
</form>
<hr/>
Probably problem with posts Id, but I'm not sure in that.
You can use get_or_create instead of the if else statement for if exist or not. And use get_object_or_404 to make code more clear.
from django.shortcuts import get_object_or_404
def addToWishList(request):
if request.method == 'POST':
post_obj = get_object_or_404(Post, pk=request.POST.get('object-id'))
Wishlist.objects.get_or_create(user=request.user, post=post_obj)
return HttpResponseRedirect(reverse('wishlist'))
In your views.py try to replace these lines:
try:
wish_item = Wishlist.objects.get(user=request.user, post=post_var)
if wish_item:
wish_item.save()
except:
Wishlist.objects.create(user=request.user, post=post_var)
with
wish_item, was_created = Wishlist.objects.get_or_create(user=request.user, post=post_var)
# for debugging
if was_created:
print(f"{wish_item} was created")
else:
print(f"{wish_item} already exists")
what is the output?
The code looks OK for me. You might add a trailing / in your urls.py after the path("add-to-wishlist/" ... but I can't spot anything wrong in the first place.
Im working n a record label website in Django 3 using Python3. (Artist, Release, Track structure)
I am attempting to filter out a list of all tracks based on the current artist page.
music/artist/
I'm thining to filter this in the context_processors file, but dont know how, and am willing to do it anyway that works if this is not possible.
artist.html
{% block body %}
<div class="container artistitem">
<h2>{{ artist.artist_name }}</h2>
<h3>{{ artist.artist_url }}</h3>
<h5>{{ artist.artist_id }}</h5>
<div class="artistimage"><img src="{{ artist.artist_logo.url }}"></div>
<div>
<h3>Discography</h3>
<p>
<ul>
<!-- for this artist id in all releases print all release name -->
<!-- {% for release.artist.id in all_releases %}
<li>
{{ release.release_title }}
</li>
{% endfor %} -->
<!-- for this artist id in all releases print all release name -->
{% for track in all_tracks_byartist %}
<li>
{{ track.track_title }}
</li>
{% endfor %}
</ul>
</p>
</div>
</div>
{% endblock %}
models.py
from django.db import models
# Create your models here.
class Artist(models.Model):
artist_name = models.CharField(max_length=250, default='')
artist_logo = models.FileField()
artist_url = models.URLField(blank=True)
def __str__(self):
return self.artist_name
class Release(models.Model):
artist = models.ForeignKey(Artist, on_delete=models.CASCADE, related_name='release')
release_title = models.CharField(max_length=500)
release_cover = models.FileField()
release_duration = models.IntegerField()
def __str__(self):
return self.release_title
class Track(models.Model):
release = models.ForeignKey(Release, default='', on_delete=models.CASCADE)
artist = models.ForeignKey(Artist, default='', on_delete=models.CASCADE)
track_title = models.CharField(max_length=200)
track_version = models.CharField(max_length=200)
track_genre = models.CharField(max_length=100)
track_duration = models.IntegerField()
track_number = models.SmallIntegerField()
class Meta:
ordering = ["track_number"]
def __str__(self):
return self.track_title
app_name = 'music'
context_processors.py
from music.models import Artist, Release, Track
def all_artists(request):
artist = Artist.objects.all()
return {'all_artists':artist}
def all_releases(request):
release = Release.objects.all()
return {'all_releases':release}
def all_tracks(request):
track = Track.objects.all()
return {'all_tracks':track}
def all_tracks_byartist(request):
track = Track.objects.all()
return {'all_tracks_byartist':track}
If you need any other files please let me know.
use reverse relation for getting tracks of a specific artist.
something like:
{% for track in artist.track_set.all %}
<li>
{{ track.track_title }}
</li>
{% endfor %}
I have two models news and category, and in news I have foreignkey of category. I know how to display news with same category in a single template. but furthermore, in my home page I'm trying to display featured news of each category. this is where I'm having problem.
this is my models.py
class News(models.Model):
title = models.CharField(max_length=120)
content = models.TextField()
category = models.ForeignKey("Tag")
active = models.BooleanField(default=True)
featured = models.BooleanField(default=False)
top = models.BooleanField(default=False)
slug = models.CharField(max_length=255, unique=True)
featuredInCat = models.BooleanField(default=False)
objects = StoryManager()
class NewsQueryset(models.query.QuerySet):
def active(self):
return self.filter(active=True)
def featuredInCat(self):
return self.filter(featuredInCat=True)
class NewsManager(models.Manager):
def get_queryset(self):
return NewsQueryset(self.model, using=self._db)
def get_featuredInCat(self):
return self.get_queryset().active().featuredInCat()
def all(self):
return self.get_queryset().active()
class Category(models.Model):
title = models.CharField(max_length=120)
description = models.TextField(max_length=5000, null=True, blank=True)
In views.py
def category_list(request):
categoryList = NewsCategory.objects.all()
featuredInCat = News.objects.get_featuredInCat()
context = {
"featuredInCat":featuredInCat
"categoryList":categoryList,
}
return render(request,"news/category_list.html", context)
In my template
{% for category in categoryList %}
<div class='col-sm-4'>
<div id="container">{{category.title}}</h1>
<ul>
{% for x in featuredInCat %}
{{x.title}}</li>
{% endfor %}
</ul>
</div>
<hr>
</div>
{% endfor %}
then this shows the featuredInCat in every category where featuredInCat should be shown only in its Category section.
how do I fix this?
Take a look at the built-in regroup template tag of django. You will need to change your template to something like this:
{% regroup featuredInCat by category as news_list %}
<ul>
{% for news in news_list %}
<li>{{ news.grouper.title }}
<ul>
{% for item in news.list %}
<li>{{ item.title }}</li>
{% endfor %}
</ul>
</li>
{% endfor %}
</ul>
You can change your for loop to iterate over the correct objects
{% for x in category.news_set.get_featuredInCat %}
You won't need the context variable anymore
I have a gallery (app in django 1.8), to which they are plugged in images. My problem is that create a link to the images in each category. I do not know how to do it on the side of the template and URL addresses are correct.
Models
class Gallery(models.Model):
title = models.CharField(max_length=200)
description = models.TextField()
image = ThumbnailerImageField(upload_to='paint/%Y/%m/%d')
class Meta:
verbose_name = "Gallery"
verbose_name_plural = " Galleries"
def __unicode__(self):
return self.title
class Paint(models.Model):
AVAILABLE = "Available"
NOT_AVAILABLE = "Not available"
STATUS_PAINT = (
(AVAILABLE, u"Dostępny"),
(NOT_AVAILABLE, u"Nie dostępny")
)
title = models.CharField(max_length=200)
gallery = models.ForeignKey(Gallery)
paint = ThumbnailerImageField(upload_to='paint/%Y/%m/%d')
price = models.CharField(max_length=50, blank=True, null=True)
status = models.CharField(choices=STATUS_PAINT, default=AVAILABLE, max_length=50)
class Meta:
verbose_name = "Picture"
verbose_name_plural = "Images"
def __unicode__(self):
return self.title
Views
class GalleryView(generic.ListView):
model = Paint
template_name = "www/gallery_list.html"
context_object_name = "gallery"
def get_queryset(self):
return Paint.objects.all()
class GalleryDetailsView(generic.ListView):
model = Gallery
context_object_name = "images"
template_name = "www/gallery_details.html"
urls
urlpatterns = [
url(r'^$', MainPage.as_view(), name='mainpage'),
url(r'^about/$', AboutMe.as_view(), name="about"),
url(r'^gallery/$', GalleryView.as_view(), name="gallery"),
url(r'^gallery1/$', GalleryDetailsView.as_view(), name="gallery_details"),
url(r'^contact/$', contact, name="contact"),
]
Template gallery list - main section
{% extends "base.html" %}
{% load thumbnail %}
{% block content %}
{% for i in images %}
<div class="row">
<div class="col-md-5">
<img src="{{ i.image|thumbnail_url:'avatar1' }}"/>
</div>
<div class="col-md-7">
<h3>{{ i.title }}</h3>
<p>{{ i.description }}</p>
</div>
</div>
<hr>
{% endfor %}
{% endblock %}
{% block content_bottom %}{% endblock content_bottom %}
Template gallery details with images of gallery
{% extends "base.html" %}
{% load thumbnail %}
{% block content %}
<table class="center-table">
<tbody>
{% for image in gallery %}
{% if forloop.counter0|divisibleby:3 %}<tr>{% endif %}
<td style="padding-left:50px;padding-right:50px;color:grey">
<a data-lightbox="roadtrip" href="{{ image.paint.url }}"><img src="{{ image.paint|thumbnail_url:'avatar' }}" class="img-thumbnail img-responsive" /></a><br>
<div style="padding-top:8px;padding-bottom:20px;">
<b>Tytuł:</b> {{ image.title }}<br>
<b>Status: </b>{{ image.status }}<br>
<b>Cena: </b>{{ image.price }}<br>
</div>
</td>
{% if forloop.counter|divisibleby:3 or forloop.last %}</tr>{% endif %}
{% endfor %}
</tbody>
</table>
{% endblock %}
{% block content_bottom %}{% endblock content_bottom %}
Ok I know a thousand people asked this but I have looked all over this site to no success(also google) here is my models.py
VENUE_IMAGE_PATH = os.path.join('images', 'venue_profiles/%Y/%m/%d')
class Venue(models.Model):
.....................
name = models.CharField(max_length=100)
address = models.CharField(max_length=100)
city = models.CharField(max_length=100)
...........................
class VenueImage(models.Model):
venue = models.ForeignKey(Venue, related_name="venue")
image = models.ImageField(upload_to=VENUE_IMAGE_PATH, max_length=255)
Here is my views.py
def list(request):
venues = Venue.objects.all()
images=VenueImage.objects.all()
return render_to_response('venues/list.html', {'venues':venues,'images':images},
context_instance = RequestContext(request))
here is my template
{% for v in venues %}
<a href='#'>{{v.name}}</a>
edit
{% if images %}
<img class='venue_image' src='images/venue_profiles/2012/10/25/{{images.url}}'
alt=''>
{% endif %}
{% endfor %}
Now I have tried {{images.images.url}} and {{images.url}}. {{MEDIA_URL}}images/venue_profiles/%Y/%m/%d/{{image.url}}.
I also tried {%for i in images %} {{i.url}} {% endfor %}.
I also tried without that 'images/venue_profiles/2012/10/25' prefix and nothing seems to work.
Can someone please help me see what I am doing wrong.
# In models.py
class Venue(models.Model):
....
name = models.CharField(max_length=100)
....
images = models.ForeignKey(VenueImage)
class VenueImage(models.Model):
image = models.ImageField(upload_to=VENUE_IMAGE_PATH)
# In views.py
def list(request):
venues = Venue.objects.all()
return render(request,
'venues/list.html',
{'venues': venues'})
# In template
{% for venue in venues %}
<a href '#'>{{ venue.name }}</a>
...
{% for image in venue.images %}
<img class='venue_image' src=''{{ image.url }}' alt=''>
{% endfor %}
{% endfor %}