How do I create a lesson in a course without it showing in another course. I have a foreign key which is the course and it is under the models Lesson. I want to only view the lesson that is created under the certain course. But my problem is when I create a lesson in course 1, the lesson also shows in course 2. (sorry for bad english)
views.py
def lessonpage(request):
lesson = Lesson.objects.all()
if request.user.is_authenticated:
return render(request, "lessons/lessons.html", {'lessons': lesson})
else:
return redirect('loginpage')
def addlesson(request):
if request.method == "POST":
form = AddLessonForm(request.POST)
if form.is_valid():
form.save()
return render(request, "lessons/successlessons.html", {'form1': form})
form = AddLessonForm()
return render(request, "lessons/addlessons.html", {'form': form})
def deletelessons(request, id):
lesson = Lesson.objects.get(id=id)
lesson.delete()
return redirect("lessonspage")
models.py
from django.db import models
class Section(models.Model):
nameofsection = models.CharField(max_length=50, default="")
def __str__(self):
return self.nameofsection
class Course(models.Model):
ctitle = models.CharField(max_length=50, default="")
cdescription = models.TextField(max_length=200, default="")
#csection = models.ForeignKey(Section, on_delete=models.CASCADE)
def __str__(self):
return self.ctitle
def __unicode__(self):
return self.ctitle
class Meta:
db_table="courses"
class Lesson(models.Model):
title = models.CharField(max_length=50, default="")
description = models.TextField(max_length=200, default="")
course = models.ForeignKey(Course, on_delete=models.CASCADE, blank=True, null=True)
def __str__(self):
return self.title
urls.py
path('course/', coursepage, name="coursepage"),
path('course/<int:pk>', CourseDetailView.as_view(), name='detailed'),
path('addcourse/', addcourse, name="addcoursepage"),
path('editcourse/<int:id>', updatecourse, name="editcoursepage"),
path('updatecourse/<int:id>', updatecourserecord, name="updatecourse"),
path('deletecourse/<int:id>', deletecourse, name="deletecourse"),
path('lessons', lessonpage, name="lessonspage"),
path('lessons/addlessons', addlesson, name="addlessonspage"),
path('deletelessons/<int:id>', deletelessons, name="deletelessons"),
Related
I am trying to get the most out of my Django Blog project and wanted to know how to show in the admin the activities that a user has made like making comments or giving likes to posts.
I need some hints and guidance on how to add this information in the admin.py
Here is the models.py in Blog App
class Post(models.Model):
title = models.CharField(max_length=100, unique=True)
content = RichTextUploadingField(null=True, blank=True)
author = models.ForeignKey(User, on_delete=models.CASCADE, related_name='author')
date_posted = models.DateTimeField(default=timezone.now)
slug = models.SlugField(blank=True, null=True, max_length=120)
liked = models.ManyToManyField(User, default=None, blank=True, related_name='liked')
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('blog:post-detail', kwargs={'slug': self.slug})
def save(self, *args, **kwargs):
if not self.slug:
self.slug = slugify(self.title)
super(Post, self).save(*args, **kwargs)
class Meta:
verbose_name_plural = 'Blog Posts'
class Comment(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
post = models.ForeignKey(Post, on_delete=models.CASCADE)
content = models.TextField(max_length=300)
updated = models.DateTimeField(auto_now=True)
created = models.DateTimeField(auto_now=True)
def __str__(self):
return f"{self.post}-{self.user}-Comment No.{self.pk}"
LIKE_CHOICES = (
('Like', 'Like'),
('Unlike', 'Unlike')
)
class Like(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
post = models.ForeignKey(Post, on_delete=models.CASCADE)
value = models.CharField(choices=LIKE_CHOICES, max_length=8)
created = models.DateTimeField(auto_now=True)
def __str__(self):
return f"{self.post}-{self.user}-{self.value}"
Here is the models.py in Users App
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
image = models.ImageField(default='default.jpg', upload_to='profile_pics')
This is what I have tried in the models.py in Users app but didn't work
# Get the no. of posts
def get_posts_no(self):
return self.author.all().count()
# Get the no. of likes
def get_likes_given(self):
likes= set.like_set.all()
total_liked=0
for item in likes:
if item.value=='Like':
total_liked+=1
return total_liked
"... to add this information in the admin.py" → do you mean to say that you would like to show an additional column in the Django admin site with said information? If so, then the answer is:
In your admin.py, extend the PostAdmin class with a custom queryset and add comments_count and likes_count to list_display = (...):
from django.contrib import admin
from django.db.models import Count
from .models import Post
class PostAdmin(admin.ModelAdmin):
list_display = ('title', 'author', 'date_posted', 'comments_count', 'likes_count')
def get_queryset(self, request):
queryset = super().get_queryset(request)
queryset = queryset.annotate(
_comments_count=Count('comment_set', distinct=True),
_likes_count=Count('like_set', distinct=True)
)
return queryset
def comments_count(self, obj):
if hasattr(obj, '_comments_count'):
return obj._comments_count
return None
def likes_count(self, obj):
if hasattr(obj, '_likes_count'):
return obj._likes_count
return None
comments_count.admin_order_field = '_comments_count'
likes_count.admin_order_field = '_likes_count'
admin.site.register(Post, PostAdmin)
I am trying to save this field from Forms.py, which seems to be causing this error: Cannot assign "<QuerySet [Vehicles: Toyota]>": "Group.vehicles" must be a "Vehicle" instance.
Everything saves correctly through the admin page but not through the form.
class GroupForm(forms.ModelForm):
vehicles = forms.ModelMultipleChoiceField(widget=forms.CheckboxSelectMultiple(), queryset=Vehicles.objects.all())
class Meta:
model = Group
Models.py:
class Vehicles(models.Model):
Vehicles = models.CharField(max_length=30, null=True, blank=True)
MaxRange = models.DecimalField(null=True, max_digits=20, decimal_places=3, default=Decimal('0.000'))
Speed = models.DecimalField(null=True, max_digits=20, decimal_places=3, default=Decimal('0.000'))
def __str__(self):
return self.Vehicles
class Group(models.Model):
group = models.CharField(max_length=30, blank=True)
vehicles = models.ForeignKey(Vehicles, null=True, on_delete=models.CASCADE)
def __str__(self):
return self.group
'Group' consists of one type of vehicle.
views.py:
def home(request):
group = Group.objects.all()
form = GroupForm()
if request.method == 'POST':
form = GroupForm(request.POST)
if form.is_valid():
obj = form.save(commit=False)
obj.vehicles = form.cleaned_data['vehicles']
obj.save()
return redirect('/')
context = {'group': group, 'form': form}
return render(request, 'calculator/Input.html', context)
Thanks you for any input
Nevermind, didn't need a checkbox widget. I deleted the line: "vehicles = forms.ModelMultipleChoiceField(widget=forms.CheckboxSelectMultiple(), queryset=Vehicles.objects.all())" and just left 'vehicle' as a field in Forms.py under class Meta: It saves/ users can only select one option now.
After makemigrations, then migrate I got this error
IntegrityError: The row in table 'main_post' with primary key '2' has an invalid foreign key: main_post.author_id cointains a value '1' that does not have a corresponding value in auth_user.id
I try some solutions in similar question but it doesnot work
My models.py
User = get_user_model()
class PostView(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, blank=True)
post = models.ForeignKey('Post', on_delete=models.CASCADE, blank=True)
def __str__(self):
return self.user.username
class Comment(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
timestamp = models.DateTimeField(auto_now_add=True)
content = models.TextField()
post = models.ForeignKey('Post', related_name='comments', on_delete=models.CASCADE)
def __str__(self):
return self.user.username
class Author(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
profile_picture = models.ImageField()
def __str__(self):
return self.user.username
class Category(models.Model):
title = models.CharField(max_length=40)
def __str__(self):
return self.title
class Post(models.Model):
title = models.CharField(max_length=100)
overview = models.TextField()
detail = models.TextField()
timestamp = models.DateTimeField(auto_now_add=True)
content = RichTextUploadingField(config_name='post_ckeditor')
author = models.ForeignKey(Author, on_delete=models.CASCADE)
thumbnail = models.ImageField()
categories = models.ManyToManyField(Category)
featured = models.BooleanField()
previous_post = models.ForeignKey('self', related_name='previous', on_delete=models.SET_NULL, blank = True, null = True)
next_post = models.ForeignKey('self', related_name='next', on_delete=models.SET_NULL, blank = True, null = True)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('post-detail', kwargs={
'id': self.id
})
def get_update_url(self):
return reverse('post-update', kwargs={
'id': self.id
})
def get_delete_url(self):
return reverse('post-delete', kwargs={
'id': self.id
})
#property
def get_comments(self):
return self.comments.all().order_by('-timestamp')
#property
def view_count(self):
return PostView.objects.filter(post=self).count()
#property
def comment_count(self):
return Comment.objects.filter(post=self).count()
My views.py
#Some code not include in this
def post(request, id):
most_recent = Post.objects.order_by('-timestamp')[:3]
category_count = get_category_count()
post = get_object_or_404(Post, id=id)
PostView.objects.get_or_create(user=request.user, post=post)
form = CommentForm(request.POST or None)
if request.method == 'POST':
if form.is_valid():
form.instance.user = request.user
form.instance.post = post
form.save()
return redirect(reverse('post-detail', kwargs={
'id':post.id
}))
context = {
'form': form,
'post': post,
'category_count':get_category_count,
'most_recent': most_recent,
}
return render(request, 'post.html', context)
Hi I'm trying to create a form that accepts Log from the user however I don't know how to pass the instance of the user. I'm used to creating a CreateView for this, however since I'm planning to use customized widgets and settings, I'm using a modelform to create logs for the user.
My question is is this the same way as create view to check the instance of the user?
Is it still the same as what I did to my createview which is:
def form_valid(self,form) :
form.instance.testuser = self.request.user
return super().form_valid(form)
Or do I have to do something else entirely?
Here is my Forms.py:
from django import forms
from profiles.models import User
from .models import DPRLog
class DateInput (forms.DateInput):
input_type = 'date'
class Datefield (forms.Form):
date_field=forms.DateField(widget=DateInput)
class dprform(forms.ModelForm):
class Meta:
model = DPRLog
widgets = {'reportDate':DateInput()}
fields = ['status','login','logout','reportDate','mainTasks','remarks']
Models.py:
from django.db import models
from profiles.models import User
from django.urls import reverse
# Create your models here.
class Points(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
points = models.IntegerField(default=0, null=False)
def __str__(self):
return self.user.username
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
image = models.ImageField(default='default.png', upload_to='profile_pics')
def __str__(self):
return f'{self.user.username} Profile'
class Manager(models.Model):
manager = models.OneToOneField(User, on_delete=models.CASCADE)
def __str__(self):
return self.manager.full_name
class Member(models.Model):
manager = models.ForeignKey(Manager, on_delete=models.CASCADE)
member = models.OneToOneField(User, on_delete=models.CASCADE)
name = models.CharField(max_length=30, null=True)
def __str__(self):
return self.member.full_name
class Job(models.Model):
manager = models.ForeignKey(Manager, on_delete=models.CASCADE)
member = models.ForeignKey(Member, on_delete=models.CASCADE)
title = models.CharField(max_length=30, blank=False, null=False)
description = models.TextField()
datePosted = models.DateTimeField(auto_now=True)
file = models.FileField(null=True, blank=True, upload_to='job_files')
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('job-detail', kwargs={'pk': self.pk})
class DPRLog(models.Model):
STATUS_CHOICES = (
('PENDING', 'PENDING'),
('CANCELLED', 'CANCELLED'),
('COMPLETED', 'COMPLETED'),
)
TASKS_CHOICES = (
('TESTS EXECUTION', 'TESTS EXECUTION'),
('TESTS DESIGN', 'TESTS DESIGN'),
('MOBILE TESTING WORKSHOP', 'MOBILE TESTING WORKSHOP'),
('BENCH ACTIVITY', 'BENCH ACTIVITY'),
('DEFECT ANALYSIS','DEFECT ANALYSIS'),
)
testuser = models.ForeignKey(User,on_delete = models.CASCADE)
status = models.CharField(max_length=30, choices=STATUS_CHOICES,null=True)
reportDate = models.DateField(blank=False, null=False)
login = models.TimeField(blank=False, null=False)
logout = models.TimeField(blank=False, null=False)
mainTasks = models.CharField(max_length=50, blank=False, choices=TASKS_CHOICES, null=True)
remarks = models.CharField(max_length=30,null=True)
def __str__(self):
return f'{self.testuser.full_name} DPR Log'
Views.py:
def dprmodelform(request):
if request.method=='POST':
form = dprform(request.POST)
if form.is_valid():
form.save()
form = dprform()
return render (request,'users/dprform.html',{'form':form})
def form_valid(self,form) :
form.instance.testuser = self.request.user
return super().form_valid(form)
class dprview(LoginRequiredMixin,ListView):
model = DPRLog
template_name = 'users/dpr_view.html'
context_object_name = 'log'
If you pass commit=False to form.save() you can get the instance from the validated form without saving to the database. You can then set the user attribute on the instance before calling save again
if form.is_valid():
instance = form.save(commit=False)
instance.testuser = request.user
instance.save()
Good day everybody.
I need to test a view, and I got stuck ( I am a django newbie).
I got through all other url and view tests, but I'm really not sure how to write this one.
I tried writing it on my own, I read through the testing docs, I even tried testing this using model_mommy ( but I got a custom HTML field in my models ) which is not supported by mommy. I tried with mommy Recipes, also without luck. I really gotta do this test today, it's a part of a task I was given.
here is the view :
class CommentCreateView(CreateView):
def get(self, request, *args, **kwargs):
context = {'form': CommentForm()}
return render(request, 'news/add_comment_to_article.html', context)
def post(self, request, *args, **kwargs):
form = CommentForm(request.POST)
if form.is_valid():
article = get_object_or_404(Article, pk=kwargs.get('pk'))
print(article)
comment = form.save(commit=False)
comment.post = article
comment.save()
return HttpResponseRedirect(reverse('news:article', kwargs={'article_id': article.pk}))
else:
form = CommentForm()
return render(request, 'news/add_comment_to_article.html', {'form': form})
and here are my models:
class Article(models.Model):
title = models.CharField('title', max_length=200, blank=True)
slug = AutoSlugField(populate_from='title', default="",
always_update=True, unique=True)
author = models.CharField('Author', max_length=200, default="")
description = HTMLField()
is_published = models.BooleanField(default=False)
article_text = HTMLField('Article text', default="")
pub_date = models.DateTimeField(default=datetime.now, blank=True)
article_category = models.ForeignKey(Category, on_delete="models.CASCADE", blank=True, null=True, default="")
my_order = models.PositiveIntegerField(default=0, blank=False, null=False)
class Meta(object):
ordering = ['my_order']
def __str__(self):
print(self.image.all())
return self.title
class ArticleImages(models.Model):
article = models.ForeignKey(Article, on_delete="models.CASCADE", related_name="image")
image = models.ImageField("image")
my_order = models.PositiveIntegerField(default=0, blank=False, null=False)
def image_tag(self):
return mark_safe('<img src="/media/%s" width="150" height="150" />' % (self.image))
image_tag.short_description = 'Image'
class Meta(object):
ordering = ['my_order']
def __str__(self):
return self.image.url
class Comment(models.Model):
post = models.ForeignKey('Article', on_delete=models.CASCADE, related_name='comments')
author = models.CharField(max_length=200)
text = models.TextField()
created_date = models.DateTimeField(default=datetime.now, blank=True)
approved_comment = models.BooleanField(default=False)
def approve(self):
self.approved_comment = True
self.save()
def __str__(self):
return self.text
I would REALLY appreciate someone helping me out here.
Thank you, and have a good day !