Hope you can help me with this one.I am very new to Python/Django so my code might be quite bad.
I am creating a website/blog and on my navigation bar I have a list of the categories which contain dropdown menues with the subcategories. When I click on each subcategory I want it to display just the posts from that subcategory.
Here is part of my code for this:
"Models":
from django.db import models
from django.utils import timezone
from django.utils.text import slugify
from django.urls import reverse
from ckeditor_uploader.fields import RichTextUploadingField
class Post(models.Model):
NO_CATEGORY = 'No Category'
GETTING_STARTED = 'Getting Started'
DIY = "DIY"
GARDENS = 'Gardens'
TERRARIUMS = 'Terrariums'
CATEGORIES = (
(NO_CATEGORY, 'No Category'),
(GETTING_STARTED, 'Getting Started'),
(DIY, 'DIY'),
(GARDENS, 'Gardens'),
(TERRARIUMS, 'Terrariums'),
)
title = models.CharField(max_length=200, unique=True)
slug = models.SlugField(unique=True, default='', blank=True)
image = models.ImageField(upload_to='images/')
content = RichTextUploadingField(null=True, blank=True)
summary = models.CharField(max_length=150, unique=True, null=True)
category = models.CharField(choices=CATEGORIES, max_length=15, default=NO_CATEGORY)
subcategory = models.ForeignKey('Subcategory', on_delete=models.SET_NULL, null=True)
created_date = models.DateTimeField(default=timezone.now)
def __str__(self):
return self.title
def save(self, *args, **kwargs):
self.slug = slugify(self.title)
super(Post, self).save(*args, **kwargs)
def get_absolute_url(self):
return reverse('core:post_detail', args=[str(self.slug)])
class Meta:
ordering = ['-created_date']
class Subcategory(models.Model):
NO_CATEGORY = 'No Category'
TOOLS = 'Tools'
HOW_TO = 'How To'
SUPPLIES = 'Supplies'
FURNITURE = 'Furniture'
ACCESSORIES = 'Accessories'
DECOR = 'Decor'
MINIATURE = 'Miniature'
MICRO = 'Micro'
OPEN = 'Open'
ENCLOSED = 'Enclosed'
SUBCATEGORIES = [
(NO_CATEGORY, 'No Category'),
('Getting Started', ((TOOLS, 'Tools'), (HOW_TO, 'How To'), (SUPPLIES, 'Supplies'),)),
('DIY', ((FURNITURE, 'Furniture'), (ACCESSORIES, 'Accessories'), (DECOR, 'Decor'),)),
('Gardens', ((MINIATURE, 'Miniature'), (MICRO, 'Micro'),)),
('Terrariums', ((OPEN, 'Open'), (ENCLOSED, 'Enclosed'),)),
]
name = models.CharField(choices=SUBCATEGORIES, max_length=15, default=NO_CATEGORY)
slug = models.SlugField(max_length=150, unique=True, null=True)
class Meta:
verbose_name = "Subcategory"
verbose_name_plural = "Subcategories"
def get_posts(self):
return Post.objects.filter(subcategories_name=self.name)
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('core:post_subcategory', kwargs={'slug': self.slug})
class Picture(models.Model):
title = models.CharField(max_length=100, unique=True)
image = models.ImageField(upload_to='images/gallery/')
created_date = models.DateTimeField(default=timezone.now)
def __str__(self):
return f'{self.title}'
class Meta:
ordering = ['-created_date']
"Views":
from django.shortcuts import render
from .models import Post, Subcategory, Picture
from django.core.paginator import Paginator
from django.views import generic
def base(request):
return render(request, 'core/base.html')
def home(request):
posts = Post.objects.all()
paginator = Paginator(posts, 5)
page = request.GET.get('page')
posts = paginator.get_page(page)
return render(request, 'core/home.html', {'posts': posts})
class PostList(generic.ListView):
model = Post
queryset = Post.objects.all().order_by('-created_date')
template_name = 'home.html'
def post_detail(request, slug=None):
post = Post.objects.get(slug=slug)
return render(request, 'core/post_detail.html', {'post': post})
class PostDetail(generic.DetailView):
model = Post
template_name = 'post_detail.html'
def post_subcategory(request):
subcategories = Subcategory.objects.all()
paginator = Paginator(subcategories, 5)
page = request.GET.get('page')
subcategories = paginator.get_page(page)
return render(request, 'core/post_subcategory.html', {'subcategories': subcategories})
class SubcategoryDetailView(generic.DetailView):
model = Subcategory
context_object_name = 'subcategory'
template_name = 'core/post_subcategory.html'
def get_queryset(self):
return Post.objects.filter(subcategory_id=self.kwargs.get('slug'))
def base_gallery(request):
pictures = Picture.objects.all()
paginator = Paginator(pictures, 16)
page = request.GET.get('page')
pictures = paginator.get_page(page)
return render(request, 'core/base_gallery.html', {'pictures': pictures})
class PictureList(generic.ListView):
queryset = Picture.objects.all().order_by('-created_date')
template_name = 'base_gallery.html'
def contact(request):
return render(request, 'core/contact.html', {'contact': contact})
"config/urls"
from django.shortcuts import render
from .models import Post, Subcategory, Picture
from django.core.paginator import Paginator
from django.views import generic
def base(request):
return render(request, 'core/base.html')
def home(request):
posts = Post.objects.all()
paginator = Paginator(posts, 5)
page = request.GET.get('page')
posts = paginator.get_page(page)
return render(request, 'core/home.html', {'posts': posts})
class PostList(generic.ListView):
model = Post
queryset = Post.objects.all().order_by('-created_date')
template_name = 'home.html'
def post_detail(request, slug=None):
post = Post.objects.get(slug=slug)
return render(request, 'core/post_detail.html', {'post': post})
class PostDetail(generic.DetailView):
model = Post
template_name = 'post_detail.html'
def post_subcategory(request):
subcategories = Subcategory.objects.all()
paginator = Paginator(subcategories, 5)
page = request.GET.get('page')
subcategories = paginator.get_page(page)
return render(request, 'core/post_subcategory.html', {'subcategories': subcategories})
class SubcategoryDetailView(generic.DetailView):
model = Subcategory
context_object_name = 'subcategory'
template_name = 'core/post_subcategory.html'
def get_queryset(self):
return Post.objects.filter(subcategory_id=self.kwargs.get('slug'))
def base_gallery(request):
pictures = Picture.objects.all()
paginator = Paginator(pictures, 16)
page = request.GET.get('page')
pictures = paginator.get_page(page)
return render(request, 'core/base_gallery.html', {'pictures': pictures})
class PictureList(generic.ListView):
queryset = Picture.objects.all().order_by('-created_date')
template_name = 'base_gallery.html'
def contact(request):
return render(request, 'core/contact.html', {'contact': contact})
"app/urls":
from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
import core.views
urlpatterns = [
path('admin/', admin.site.urls),
path('core/', include('core.urls')),
path('ckeditor/', include('ckeditor_uploader.urls')),
path('', core.views.home, name='home'),
path('', core.views.base, name='base'),
path('post_subcategory', core.views.post_subcategory, name='post_subcategory'),
path('post_detail', core.views.post_detail, name='post_detail'),
path('base_gallery', core.views.base_gallery, name='base_gallery'),
path('contact', core.views.contact, name='contact')
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
"post_category.html":
{% extends "core/base.html" %}
{% block content %}
{% load static %}
<div class="category-title">
<h1>HOW TO</h1>
</div>
{% for subcategory in subcategories %}
{% for post in subcategory.post_set.all %}
<h1>{{ post.title }}</h1>
<div class="category-content">
<figure class="gallery-picture">
<h1 class="picture-text"></h1>
<img src="{{ post.image.url }}" alt="gallery image">
</figure>
</div>
{% endfor %}
{% endfor %}
{% endblock %}
This is what I've tried so far and I can display all the subcategories on that template but I don't know how to filter them one by one, if that makes any sense.
First, I think the data structure and your model relationships are not properly placed.
I think you should have a category model and a sub_category model too.
class Category(models.Model):
title = models.Charfield(...)
class SubCategory(models.Model):
category = models.ForiegnKey(on_delete=models.CASCADE)
title = models.Charfield(...)
By doing this, you wouldn't need the dictionary and you won't also need the category field on Post model
so all have to query in your views.py is where post.sub_category.category == the requested category or where post.sub_cateogory == the requested sub_category.
Editing to show how to implement in views.py
class DIYCategoryList(generic.ListView):
template_name = 'blog/diy_category.html'
model = Post
context_object_name = 'diy_posts'
paginate_by = 16
def get_queryset(self):
return Post.objects.filter(sub_category.category.title='DIY')
Related
I have just started learning the django framework and I am having issues while displaying the images from the database to the frontend of the website. My database is showing the images uploaded but nothing is being displayed on the page itself.
This is my models.py
class Post(models.Model):
title= models.CharField(max_length=255)
author= models.ForeignKey(User,on_delete=models.CASCADE)
body = models.TextField()
def get_absolute_url(self):
return reverse('article-detail', args=(str(self.id)))
def __str__(self):
return self.title + ' | ' + str(self.author)
class Images(models.Model):
post= models.ForeignKey(Post,on_delete=models.CASCADE )
image= models.ImageField(null=True, blank=True)
This is my views.py
class ArticleDetailView(DetailView):
model = Post
template_name= 'article_details.html'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['imagelist'] = Post.objects.get(id = self.kwargs['pk'])
return context
def AddPostView(request):
model= Images
if request.method == "POST":
form= PostForm(request.POST)
files = request.FILES.getlist("image")
if form.is_valid():
f=form.save(commit=False)
f.user=request.user
f.save()
for i in files:
img = Images.objects.create(post=f, image= i)
img.save()
messages.success(request, "New Blog added")
return HttpResponseRedirect("/")
else:
form= PostForm()
imageform= ImageForm()
return render (request, "add_post.html",{"form":form,"imageform":imageform})
This is my forms.py
from django import forms
from .models import Images, Post
class PostForm(forms.ModelForm):
class Meta:
model= Post
fields = ('title', 'body','author')
widgets = {
'title': forms.TextInput(attrs{'class':'form-control'}),
'body': forms.Textarea(attrs={'class':'form-control'})
}
class ImageForm(forms.ModelForm):
image= forms.ImageField(
label="image",
widget= forms.ClearableFileInput(attrs={"multiple":True}),
)
class Meta:
model= Images
fields= ("image",)
This is my artice-details.html page
{% for pimage in imageslist.image_set.all %}
<img src="{{pimage.image.url}}" alt="default">
{% endfor %}
I'm new to Django so this is probably a dumb question but,
when I put the class Category model above the class Post model I get an
NameError: name 'Post' is not defined error.
but when I try to put class Category model underneath the Post model (as in the code here) I get
categories = models.ManyToManyField(Category)
NameError: name 'Category' is not defined error.
models.py
class Post(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
date_posted = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(User, on_delete=models.CASCADE) #if is deleted than delete their posts
location = models.CharField(max_length=100, default="")
tags = TaggableManager()
likes = models.ManyToManyField(User, related_name='blog_posts')
categories = models.ManyToManyField(Category)
def total_likes(self):
return self.likes.count()
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('post-detail', kwargs={'pk': self.pk})
class Category(models.Model):
post = models.ForeignKey(Post, related_name="categories")
name = models.CharField(max_length=20)
def __str__(self):
return self.name
admin.py
from django.contrib import admin
from .models import Post, Comment, Category #, Konum
# Register your models here.
admin.site.register(Post)
admin.site.register(Comment)
admin.site.register(Category)
#admin.site.register(Konum)
some of the code
<form method="GET" action=".">
<div class="form-group col-md-4">
<label for="category">Category</label>
<select id="category" class="form-control" name="category">
<option selected>Choose...</option>
{% for cat in categories %}
<option value="{{ cat }}">{{ cat }}</option>
{% endfor %}
</select>
</div>
<button type="submit" class="btn btn-primary">Search</button>
</form>
views.py
def home(request):
context = {
"posts": Post.objects.all()
}
return render(request, 'blog/home.html', context)
#--------------------------------------------------------------------------------------------------------------------------------------#--------------------------------------------------------------------------------------------------------------------------------------#--------------------------------------------------------------------------------------------------------------------------------------
#--------------------------------------------------------------------------------------------------------------------------------------#--------------------------------------------------------------------------------------------------------------------------------------#--------------------------------------------------------------------------------------------------------------------------------------
#--------------------------------------------------------------------------------------------------------------------------------------#--------------------------------------------------------------------------------------------------------------------------------------#--------------------------------------------------------------------------------------------------------------------------------------
#--------------------------------------------------------------------------------------------------------------------------------------#--------------------------------------------------------------------------------------------------------------------------------------#--------------------------------------------------------------------------------------------------------------------------------------
#--------------------------------------------------------------------------------------------------------------------------------------#--------------------------------------------------------------------------------------------------------------------------------------#--------------------------------------------------------------------------------------------------------------------------------------
#--------------------------------------------------------------------------------------------------------------------------------------#--------------------------------------------------------------------------------------------------------------------------------------#--------------------------------------------------------------------------------------------------------------------------------------
#--------------------------------------------------------------------------------------------------------------------------------------
def filter(request):
qs = Post.objects.all()
categories = Category.objects.all()
id_exact_query = request.GET.get('id_exact')
title_or_author_query = request.GET.get('title_or_author')
category = request.GET.get('category')
if is_valid_queryparam(category) and category != 'Choose...':
qs = qs.filter(categories__name=category)
context = {
'posts': qs,
'categories': Category.objects.all()
}
return render(request, 'blog/home.html', context)
class PostListView(ListView):
model = Post
template_name = 'blog/home.html'
context_object_name = 'posts'
ordering = ['-date_posted']
paginate_by = 199
class UserPostListView(ListView):
model = Post
template_name = 'blog/user_posts.html'
context_object_name = 'posts'
paginate_by = 199
def get_queryset(self):
return Post.objects.filter(author = user).order_by('-date_posted')
urls.py
from django.urls import path, re_path
from .import views
from .views import PostListView, PostDetailView, PostCreateView, PostUpdateView, PostDeleteView, UserPostListView, TagIndexView, LikeView #, LocationPostListView
urlpatterns = [
path('', PostListView.as_view(), name="blog-home"), #has a empty strting bc its already processed blog part in main urls
path('user/<str:username>', UserPostListView.as_view(), name="user-posts"),
#--------------------------------------------------------------------------------------------------------------------------------------
#path('location/<str:loc>', LocationPostListView.as_view(), name="location-posts"),
#--------------------------------------------------------------------------------------------------------------------------------------
path('post/<int:pk>/', PostDetailView.as_view(), name='post-detail'),#pk means primary key like post 1 post 2 etc
path('post/new/', PostCreateView.as_view(), name='post-create'),
path('post/<int:pk>/update/', PostUpdateView.as_view(), name='post-update'),
path('post/<int:pk>/delete/', PostDeleteView.as_view(), name='post-delete'),
path('about/', views.about, name="blog-about"),
#--------------------------------------------------------------------------------------------------------------------------------------
path('tag/<slug:slug>/', TagIndexView.as_view(), name='tagged'),
path('like/<int:pk>', LikeView, name='like_post'),
#--------------------------------------------------------------------------------------------------------------------------------------
]
You can use a string literal to specify the model name of a model that still needs to be defined, so you can use ManyToManyField('Category') or ForeignKey('Post', on_delete=models.CASCADE) for example to refer to models not yet defined:
from django.conf import settings
class Post(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
date_posted = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
location = models.CharField(max_length=100, default="")
tags = TaggableManager()
likes = models.ManyToManyField(settings.AUTH_USER_MODELS, related_name='liked_posts')
categories = models.ManyToManyField('Category')
It however does not seem to make much sense that a Category has a ForeignKey to a post: that would mean that a Category links to exactly one Post record?
You can for example use a ListView with:
class PostListView(ListView):
model = Post
template_name = 'blog/home.html'
context_object_name = 'posts'
ordering = ['-date_posted']
paginate_by = 199
def get_queryset(self):
qs = super().get_queryset()
if self.request.GET.get('category'):
return qs.filter(categories__name=self.request.GET['category'])
return qs
def get_context_data(self, *args, **kwargs):
context = super().get_queryset(*args, **kwargs)
context['categories'] = Category.objects.all()
return context
Note: It is normally better to make use of the settings.AUTH_USER_MODEL [Django-doc] to refer to the user model, than to use the User model [Django-doc] directly. For more information you can see the referencing the User model section of the documentation.
I have tried to look at similar questions but can't seem to get a way around this bug.
NoReverseMatch at /groups/
Reverse for 'for_user' with keyword arguments '{'username': ''}' not found. 1 pattern(s) tried: ['posts/by/(?P[-\w]+)/$']
models.py
from groups.models import Group
# Create your models here.
from django.contrib.auth import get_user_model
User = get_user_model()
class Post(models.Model):
user = models.ForeignKey(User,related_name='posts',
on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now=True)
message = models.TextField()
message_html = models.TextField(editable='False')
group = models.ForeignKey(Group,related_name='posts',
null=True,blank=True,on_delete=models.CASCADE)
def __str__(self):
return self.message
def save(self,*args,**kwargs):
self.message_html = misaka.html(self.message)
super().save(*args,**kwargs)
def get_absolute_url(self):
return reverse(
'posts:single',
kwargs={'username':self.user.username,
'pk':self.pk})
class Meta:
ordering = ['-created_at']
unique_together = ['user','message']
Views.py
class PostList(SelectRelatedMixin,generic.ListView):
model = models.Post
select_related = ('user','group')
class UserPosts(generic.ListView):
model = models.Post
template_name = "posts/user_post_list.html"
def get_queryset(self):
try:
self.post_user = User.objects.prefetch_related("posts").get(
username__iexact=self.kwargs.get("username")
)
except User.DoesNotExist:
raise Http404
else:
return self.post_user.posts.all()
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["post_user"] = self.post_user
return context
class PostDetail(SelectRelatedMixin,generic.DetailView):
model = models.Post
select_related = ('user','group')
def get_queryset(self):
queryset = super().get_queryset()
return queryset.filter(user__username__iexact=self.kwargs.get('username'))
class CreatePost(LoginRequiredMixin,SelectRelatedMixin,generic.CreateView):
fields = ('message','group')
model = models.Post
def form_valid(self,form):
self.object = form.save(commit=False)
self.object.user = self.request.user
self.object.save()
return super().form_valid(form)
class DeletePost(LoginRequiredMixin,SelectRelatedMixin,generic.DeleteView):
model = models.Post
select_related = ('user','group')
success_url = reverse_lazy('posts:all')
def get_queryset(self):
queryset = super().get_queryset()
return queryset.filter(user_id = self.request.user.id)
def delete(self,*args,**kwargs):
messages.success(self.request,'Post Deleted')
return super().delete(*args,**kwargs)
##POSTS URLS
from django.urls import re_path
from . import views
app_name = 'posts'
urlpatterns = [
re_path(r'^$',views.PostList.as_view(),name='all'),
re_path(r'newpost/$',views.CreatePost.as_view(),name='create'),enter code here
re_path(r"by/(?P<username>[-\w]+)/$",views.UserPosts.as_view(),
name="for_user"),
re_path(r"by/(?P<username>[-\w]+)/(?P<pk>\d+)/$",views.PostDetail.as_view(),
name="single"),
re_path(r'delete/(?P<pk>\d+)/$',views.DeletePost.as_view(),name='delete'),
]
Thanks #Razenstein .... It was a template error....
'''
{% extends "groups/group_base.html" %}
{% block pregroup %}
<div class="col-md-4">
<div class="content">
{% if user.is_authenticated %}
<h2>
Welcome Back!
<a href="{% url 'posts:for_user' username=user.username
%}">#{{user.username}}</a>
</h2>
{% endif %}
'''
I had written <a href="{% url 'posts:for_user' username=user.name
I have three apps (Internship, UserProfile and Infrastructure) in my django project. I have made models Profile and StudentProject in UserProfile Model. The StudentProject Model contains two foreign key-> user and Lab (this model is defined in the Infrastructure model). In a template(details.html file) in Infrastructure app, i want to retrieve all StudentProjects who have their foreign key as the lab whose details are currently being shown. I am unable to bring the student projects created here. Please help someone. I have already tried to use filter but it doesn't work!
userprofile/models.py file
from django.conf import settings
from django.db import models
from django.core.urlresolvers import reverse
from infrastructure.models import Lab
class Profile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
name = models.CharField(max_length=100)
type = models.CharField(max_length=100)
profile_picture = models.FileField()
skills = models.CharField(max_length=1000)
def get_absolute_url(self):
return reverse('userprofile:index')
def __str__(self):
return self.name
class StudentProject(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
title = models.CharField(max_length=100)
project_picture = models.FileField()
lab = models.ForeignKey(Lab)
mentor = models.CharField(max_length=100)
domain = models.CharField(max_length=100)
description = models.CharField(max_length=1000)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('userprofile:index')
infrastructure/models.py file
from django.db import models
from django.core.urlresolvers import reverse
class Lab(models.Model):
name = models.CharField(max_length=100)
department = models.CharField(max_length=100)
description = models.CharField(max_length=1000)
lab_logo = models.FileField()
def get_absolute_url(self):
return reverse('infrastructure:details', kwargs={'pk': self.pk})
def __str__(self):
return self.name
infrastructure/templates/details.html
->This is where i want all student projects of lab to be shown
{% extends 'infrastructure/base.html' %}
{% block body %}
<h1>This is details page</h1>
<img src="{{ lab.lab_logo.url }}" style="width: 300px;">
<h1>{{ lab.name }}</h1>
<h2>{{lab.projects}}</h2>
{% endblock %}
infrastructure/views.py file
from django.core.urlresolvers import reverse_lazy
from django.views import generic
from infrastructure.models import Lab
from django.views.generic.edit import CreateView, UpdateView, DeleteView
class IndexView(generic.ListView):
template_name = 'infrastructure/index.html'
context_object_name = 'all_labs'
def get_queryset(self):
return Lab.objects.all()
class DetailView(generic.DetailView):
model = Lab
template_name = 'infrastructure/details.html'
class LabCreate(generic.CreateView):
model = Lab
fields = ['name', 'department', 'description', 'lab_logo']
class LabUpdate(generic.UpdateView):
model = Lab
fields = ['name', 'department', 'description', 'lab_logo']
class LabDelete(DeleteView):
model = Lab
success_url = reverse_lazy('infrastructure:index')
infrastructure/urls.py file
from django.conf.urls import url
from . import views
app_name = 'infrastructure'
urlpatterns = [
url(r'^$', views.IndexView.as_view(), name='index'),
url(r'^(?P<pk>[0-9]+)/$', views.DetailView.as_view(), name='details'),
url(r'^lab/add/$', views.LabCreate.as_view(), name='lab-add'),
url(r'^lab/(?P<pk>[0-9]+)/$', views.LabUpdate.as_view(), name='lab-update'),
url(r'^lab/(?P<pk>[0-9]+)/delete/$', views.LabDelete.as_view(), name='lab-delete'),
]
userprofile/views.py file
from django.contrib.auth import login, authenticate, logout
from django.http import request
from django.shortcuts import render, redirect, get_object_or_404
from django.urls import reverse_lazy
from .models import Profile, StudentProject
from django.views.generic.edit import CreateView, UpdateView, DeleteView
from .forms import UserForm
from django.views import generic
from django.views.generic import View
class IndexView(generic.TemplateView):
template_name = 'userprofile/index.html'
context_object_name = 'user_profile'
def get_queryset(self):
return request.user.get_profile()
class ProfileCreate(CreateView):
model = Profile
fields = ['user', 'name', 'type', 'profile_picture', 'skills']
class ProfileUpdate(UpdateView):
model = Profile
fields = ['user', 'name', 'type', 'profile_picture', 'skills']
class StudentProjectCreate(CreateView):
model = StudentProject
fields = ['user', 'title', 'project_picture', 'lab', 'mentor', 'domain', 'description']
class StudentProjectUpdate(UpdateView):
model = StudentProject
fields = ['user', 'title', 'project_picture', 'lab', 'mentor', 'domain', 'description']
class StudentProjectDelete(DeleteView):
model = StudentProject
success_url = reverse_lazy('userprofile:index')
def logout_view(request):
logout(request)
return render(request, 'userprofile/logout.html')
# for new user
class UserFormView(View):
form_class = UserForm
template_name= 'internship/registration_form.html'
# display blank form
def get(self, request):
form = self.form_class(None)
return render(request, self.template_name, {'form': form})
# process from data
def post(self, request):
form = self.form_class(request.POST)
if form.is_valid():
user = form.save(commit=False)
# cleaned (normalized) data
username = form.cleaned_data['username']
password = form.cleaned_data['password']
user.set_password(password)
user.save()
# return User object if credentials are correct
user = authenticate(username=username, password=password)
if user is not None:
if user.is_active:
login(request, user)
return redirect('userprofile:profile-add')
return render(request, self.template_name, {'form': form})
userprofile/urls.py file
from django.conf.urls import url, include
from django.contrib.auth import views as auth_views
from userprofile import views
app_name = 'userprofile'
urlpatterns = [
url(r'^$', views.IndexView.as_view(), name='index'),
url(r'^profile/add/$', views.ProfileCreate.as_view(), name='profile-add'),
url(r'^profile/(?P<pk>[0-9]+)/$', views.ProfileUpdate.as_view(), name='profile-update'),
url(r'^logout$', views.logout_view, name='logout_view'),
url(r'^login/$', auth_views.login, {'template_name': 'userprofile/login.html'}),
url(r'^register/$', views.UserFormView.as_view(), name='register'),
url(r'^studentproject/add/$', views.StudentProjectCreate.as_view(), name='student-project-add'),
url(r'^studentproject/(?P<pk>[0-9]+)/$', views.StudentProjectUpdate.as_view(), name='student-project-update'),
url(r'^studentproject/(?P<pk>[0-9]+)/delete/$', views.StudentProjectDelete.as_view(), name='student-project-delete'),
]
Basically, you need to add related_name argument to your declaration of Lab Field in StudentProject Model. That will make children accessible from parent Model further:
class StudentProject(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
title = models.CharField(max_length=100)
project_picture = models.FileField()
lab = models.ForeignKey(Lab, related_name=projects)
...
And now, in your template, you can easily iterate over your current lab's projects:
{% extends 'infrastructure/base.html' %}
{% block body %}
<h1>This is details page</h1>
<img src="{{ lab.lab_logo.url }}" style="width: 300px;">
<h1>{{ lab.name }}</h1>
{% for project in lab.projects_set.all %}
<h2>{{project.title}}</h2>
{% endfor %}
{% endblock %}
I have categories of the news and news and i don't know how to render the page with the list of news that belong to the same category. Hope You will help me with that.
this is my model.py file:
from django.db import models
class Category(models.Model):
class Meta:
verbose_name_plural = u'Categories'
category = models.CharField(max_length=255)
slug = models.CharField(max_length=255)
def __unicode__(self):
return self.category
class News(models.Model):
class Meta:
verbose_name_plural = u'News'
title = models.CharField(max_length=255)
category = models.ForeignKey(u'Category', related_name=u'Category', blank=True, null=True)
pub_date = models.DateTimeField('date published')
slug = models.CharField(max_length=255)
short_content=models.TextField(max_length=2000, blank=True)
content = models.TextField(max_length=10000)
image = models.FileField(u'Images', upload_to='media/img/news', blank=True)
def __unicode__(self):
return self.title
views.py:
from django.shortcuts import render
from django.views.generic import ListView, DetailView
from news.models import News
class NewsListView(ListView):
template_name ='news/list.html'
context_object_name = 'news_list'
def get_queryset(self):
return News.objects.order_by('-pub_date') [:5]
class NewsDetailView(DetailView):
model=News
template_name = 'news/detail.html'
def CategoryNews(request, categoryslug):
category = Category.objects.get(slug=categoryslug)
news = News.objects.filter(category=category)
return render (request, 'news/category_news.html', {'category' : category})
urls.py:
django.conf.urls import patterns, url
from news.views import NewsListView, NewsDetailView
from news import views
urlpatterns = patterns('',
url(r'^$', NewsListView.as_view(), name='list'),
url(r'^(?P<slug>[-_\w]+)/$', NewsDetailView.as_view()),
url(r'^kids-garden/$', views.CategoryNews),
)
Thank You!
On CategoryNews view add news to render context. This will make news items available in templates.
def CategoryNews(request, categoryslug):
category = Category.objects.get(slug=categoryslug)
news = News.objects.filter(category=category)
return render (request, 'news/category_news.html', {'category' : category, 'newsitems': news})
Add named group to category url to make it dynamic.
Rewrite
url(r'^kids-garden/$', views.CategoryNews, name='category'),
to
url(r'^category/(?P<categoryslug>\w+)/$', views.CategoryNews, name='category'),
In category_news.html
{%for news in newsitems%}
{{ news.title }}
{{ news.content }}
# rest values...........
{% endfor %}
I think this should do the job:
views.py
....
from news.models import News, Category
def CategoryNews(request, categoryslug):
category_news = News.objects.filter(category__slug='categoryslug')
return render (request, 'news/category_news.html', {'category_news' : category_news})