Cannot query "Python Tutorials Teaser": Must be "Subject" instance - python-3.x

I am creating E-Learning website and I want to show "Course Content or Lession" as a playlist which is related to subject. Like that image
but I am getting error Cannot query "Python Tutorials Teaser": Must be "Subject" instance. Python Tutorials Teaser is title of the lession.
view.py
def allsubject(request):
subj = Subject.objects.all()
context = {'subj': subj}
return render(request, 'allsubject.html', context)
def pvideos(request, slug):
vds = Videos.objects.filter(slug=slug).first()
coursecontent = Videos.objects.filter(subject=vds)
context = {'vds':vds, 'coursecontent':coursecontent}
return render(request, 'pvideos.html', context)
models.py
class Videos(models.Model):
sno = models.AutoField(primary_key=True)
title = models.CharField(max_length=500)
cont = models.TextField()
vurl = models.URLField(max_length=200)
subject = models.ForeignKey(Subject, on_delete=models.CASCADE, related_name='videos')
position = models.PositiveSmallIntegerField(verbose_name="videono.")
slug = models.CharField(max_length=130)
timeStamp = models.DateTimeField(default=now)
def __str__(self):
return self.title
pvideo.html
{% extends 'base.html' %}
{% block title %}Free Video Course {% endblock title %}
{% block body %}
<div class="container">
<div class="embed-responsive embed-responsive-21by9">
<iframe class="embed-responsive-item" src="{{vds.vurl}}" allowfullscreen></iframe>
</div>
<ul class="nav nav-tabs" id="myTab" role="tablist">
<li class="nav-item">
<a class="nav-link active font-weight-bold" id="home-tab" data-toggle="tab" href="#overview" role="tab"
aria-controls="home" aria-selected="true">Overview</a>
</li>
<li class="nav-item">
<a class="nav-link font-weight-bold" id="profile-tab" data-toggle="tab" href="#coursecontent" role="tab"
aria-controls="profile" aria-selected="false">Course Content</a>
</li>
</ul>
<div class="tab-content" id="myTabContent">
<div class="tab-pane fade show active" id="overview" role="tabpanel" aria-labelledby="home-tab">
<h2>{{vds.title}}</h2>
<p>{{vds.cont|safe}}</p>
</div>
<div class="tab-pane fade" id="coursecontent" role="tabpanel" aria-labelledby="profile-tab">
{% for c in coursecontent %}
{{c.title}}
{% endfor %}
</div>
</div>
</div>
{% endblock body %}
I think I made a mistake on views.py coursecontent = Videos.objects.filter(subject=vds). I want to show this playlist on that page where I show lessions. I hope you understand what I want. If anyone has any other idea besides this, so please help me.
I user click on course content then I show all lession related to subject

You are right, you have made a mistake in coursecontent = Videos.objects.filter(subject=vds)
Subject must either be the pk or an instance of subject but you're giving it another video instance. What you want is
coursecontent = Videos.objects.filter(subject=vds.subject).exclude(sno=vds.sno)
.filter(subject=vds.subject) will give you all videos with the same subject.
.exclude(sno=vds.sno) will exclude the current video from the query. This is useful if you want to show only the other videos... If you want to include all, just skip that part.
As a side note, you might want to improve your variable naming.
vds could be called video (it's singular)
vurl could be just url
cont could be content
Most of your model names should be singular (coz each is a single instance).
An e-learning website is a nice initiative.

Related

How to display extra context and form fields at the same time on django template using class based view?

I am trying to display some extra context on the page, but when I adding get_context_data method it is displayed context but not a forms fields. This is because when I click ulr that triggers view below there is get method by default or prior to forms fields? I don't understand why forms disappear when this method present in SolutionCreate view, indeed all context data displayed
template
{% extends "base.html" %}
{% block content %}
<div class="container">
<div class="row">
<div class="col-sm">
<form action="" method="POST">
<table>
{% csrf_token %}
{{ form.as_p }}
</table>
<input type="submit" class="btn btn-primary" value="Submit">
</form>
</div>
<div class="col-sm">
{{ context }}
<h5>Problem:</h5>
{% for pr in prb %}
<h5>Problem: {{ pr.title }}</h5>
<h6>Description</h6>
<li class="list-group-item">{{ pr.description }}</li>
<p>
</p>
<h6>Risks</h6>
<li class="list-group-item">{{ pr.risks }}</li>
<p>
</p>
<h6>Parts</h6>
<li class="list-group-item">{{ pr.parts }}</li>
<p>
</p>
<h6>Causes</h6>
<li class="list-group-item">{{ pr.causes }}</li>
<p>
</p>
<h6>Published</h6>
<li class="list-group-item">{{ pr.published }}</li>
<p>
</p>
<a href="{% url 'delete_problem' pr.pk %}"
class="btn btn-warning"
role="button"
aria-pressed="true">Delete</a>
<a href="{% url 'update_problem' pr.pk %}"
class="btn btn-warning"
role="button"
aria-pressed="true">Update</a>
<p>
</p>
{% endfor %}
</div>
</div>
</div>
{% endblock content %}
view
class SolutionCreate(CreateView):
model = Solution
template_name = 'analysis/create_solution.html'
fields = [
'problem',
'research',
'solutions',
'resources',
'plan',
'test'
]
def post(self, request, *args, **kwargs):
form = SolutionForm(request.POST)
if form.is_valid():
form.save(commit=True)
return HttpResponseRedirect('/saved/')
return render(request, self.template_name, {'form': form})
def get_context_data(self, *args, **kwargs):
prb = Problem.objects.select_related()
return {'prb': prb}
get_context_data is a method on the parent class. If you override it, you still need to call the parent method which is what adds the form to the context. You do this by calling super() inside your own method, to obtain the context data, and then add your own:
def get_context_data(self, *args, **kwargs):
context = super().get_context_data(*args, **kwargs)
context['prb'] = Problem.objects.select_related()
return context
Refer to the documentation on adding extra context to see how you should use get_context_data.
This worked for me in a similar scenario
def get_context_data(self, *args, **kwargs):
context = super().get_context_data(**kwargs)
prb = Problem.objects.select_related()
context.update({'prb': prb})
return context

saving image URL using django shell

I want to save the url of images in my database using django shell
here is my model
class Album(models.Model):
reference = models.IntegerField(null = True)
created_at = models.DateTimeField(auto_now_add=True)
available = models.BooleanField(default=True)
title = models.CharField(max_length=200)
picture = models.URLField()
artists = models.ManyToManyField(Artist, related_name='albums', blank=True)
here is what i did in the shell
album = Album.objects.create(title="Funambule", picture="/home/etali/Images/moi.png")
the url is correctly save in the database but it's impossible to load it in the view
here is the view
<div class="col-sm-4 text-center">
<a href="/">
<img class="img-responsive" src="{{ album.picture }}" alt="{{ album.title }}">
</a>
<h3>{{ album.title }}</h3>
{% for artist in album.artists.all %}
<p>{{ artist.name }}</p>
{% endfor %}
</div>
here is the error that appears when I inspect the code

How do I add Pagination to a table (Django)

I am trying to add pagination to one of the tables for my project, but I can't find any good resources to refer to, all of the docs use some kind of URL query, but I don't want to do that, since it is on the user page.
Background --- I am making a mock website for trading for a project and I need the user to be able to see their trade history, and as you can imagine, after any more than 10, the page starts to look very long, so I am trying to find a way to make the table have pages, but I just can't figure it out.
Aim -- To add pages to a bootstrap table. The table should be able to go back and forth using buttons.
My "solution" - after going through stuff for about an hour, I found this but I don't know if it is good/safe.
Code :
VIEW -
def userPage(request):
user = request.user
user_info = user.info
trades = user_info.trade_set.all().order_by('-time_bought_at') ###I want this queryset to be paginated
total_trades = trades.count()
balance = round(user_info.balance)
context = {
"user" : user,
"user_info" : user_info,
"trades" : trades,
"total_trades" : total_trades,
"balance" : balance,
}
return render(request, "accounts/user.html", context)
I render it as :
this is the table that I want to paginate :)
<div class="row">
<div class="card card-body">
<table class="table table-sm">
<tr>
<th>Stock</th>
<th>Action</th>
<th>Price</th>
<th>No. of Stocks</th>
<th>Total Cost of Trade</th>
<th>Time of Purchase</th>
<th>Balance</th>
</tr>
{% for trade in trades %}
<tr>
<td>{{trade.ticker}}</td>
<td>{{trade.action}}</td>
<td>{{trade.price_trade_at}}</td>
<td>{{trade.stocks_bought}}</td>
<td>{{trade.cost_of_trade}}</td>
<td>{{trade.time_bought_at}}</td>
<td>{{trade.balance_of_trader_after_purchase}}</td>
</tr>
{% endfor %}
</table>
</div>
</div>
</div>
Please point me in the correct direction, I got no clue.
Try using ajax to serve your table
def userPage(request):
user = request.user
user_info = user.info
trades = user_info.trade_set.all()
total_trades = trades.count()
balance = round(user_info.balance)
context = {
"user" : user,
"user_info" : user_info,
"total_trades" : total_trades,
"balance" : balance,
}
return render(request, "accounts/user.html", context)
class TradesListView(ListView):
template_name = 'mytemplate.html'
ordering = '-time_bought_at'
paginate_by = 10
def get_queryset(self):
user_info = self.request.user.info
self.queryset = user_info.trade_set.all()
return super().get_queryset()
In the templates:-
In the template for the trades list view:-
<div class="card card-body">
<table class="table table-sm">
<tr>
<th>Stock</th>
<th>Action</th>
<th>Price</th>
<th>No. of Stocks</th>
<th>Total Cost of Trade</th>
<th>Time of Purchase</th>
<th>Balance</th>
</tr>
{% for trade in page_obj %}
<tr>
<td>{{trade.ticker}}</td>
<td>{{trade.action}}</td>
<td>{{trade.price_trade_at}}</td>
<td>{{trade.stocks_bought}}</td>
<td>{{trade.cost_of_trade}}</td>
<td>{{trade.time_bought_at}}</td>
<td>{{trade.balance_of_trader_after_purchase}}</td>
</tr>
{% endfor %}
</table>
</div>
<div class="pagination">
<span class="step-links">
{% if page_obj.has_previous %}
<button class="page-change-btn" data-url="{% url 'trades-list-view-name' %}?page=1">« first</button>
<button class="page-change-btn" data-url="{% url 'trades-list-view-name' %}?page={{ page_obj.previous_page_number }}">previous</button>
{% endif %}
<span class="current">
Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.
</span>
{% if page_obj.has_next %}
<button class="page-change-btn" data-url="{% url 'trades-list-view-name' %}?page={{ page_obj.next_page_number }}">next</button>
<button class="page-change-btn" data-url="{% url 'trades-list-view-name' %}?page={{ page_obj.paginator.num_pages }}">last »</button>
{% endif %}
</span>
</div>
In the template for the userPage:-
<div class="row" id="trades-table-container" data-url="{% url 'trades-list-view-name' %}">
</div>
Now use some javascript to perform ajax and use the url in the data-url of above div and fill the content of response into the div.
Also add javascript on the page-change-btn class in similar fashion

Exception Value: Cannot use None as a query value Django Framework

Help required, please.
I'm doing a level 6 Diploma in Software Development. Right now I'm doing a project that requires a gym app to be built.
We've decided on using Python/Django as our language/framework.
I have my models, urls, views, and templates working thus far. (Videos display and its own page)
However, I need to implement a search bar to search both video content and text context within the app.
I have the video model set up in /admin. migrations are done.
Do I need another model to search for normal content in my app?
The search bar is in my base.html template.
I want to use the search bar to do a query and pass the results onto a results template page
which extends base.html.
The error I get is the below;
Exception Type: ValueError
Exception Value: Cannot use None as a query value
Can someone point me in the right direction? photos of code attached.
base.html
<!-- Navbar Right Side -->
<div class="navbar-nav">
<form class="form-inline my-1 my-lg-0" action="{% url 'search_results' %}" method="get">
<input name="q" type="text" placeholder="Search" aria-label="Search">
<a class="btn btn-secondary my-2 my-sm-0" href='/gymapp/videos/' type=submit>Search</a>
</form>
<a class="nav-item nav-link" href="#">Login</a>
<a class="nav-item nav-link" href="/register">Register</a>
</div>
search_results.html
{% extends "gymapp/base.html" %}
{% load embed_video_tags %}
{% block content %}
{% for i in obj %}
{% video i.video 'tiny' %}
<ul class="list-unstyled mt-3 mb-4">
<li>Name: {{ i.video_name }}</li>
<li>Description: {{ i.content }}</li>
</ul>
{% endfor %}
{% endblock content %}
urls.py
path('videos/', VideoResultsView.as_view(), name='search_results'),
models.py
from django.db import models
from embed_video.fields import EmbedVideoField
class Video(models.Model):
category = models.CharField(max_length=200)
video_name = models.CharField(max_length=200)
content = models.CharField(max_length=500)
video = EmbedVideoField() # same like models.URLField()
stats = models.CharField(max_length=20)
class Meta:
verbose_name_plural = 'videos'
def __str__(self):
return self.category
views.py
class VideoResultsView(ListView):
model = Video
template_name = 'search_results.html'
def get_queryset(self):
query = self.request.GET.get('q')
video_list = Video.objects.filter(
Q(category__icontains=query) | Q(video_name__icontains=query)
)
return video_list
Hoping someone can point me in the right direction. Error Description
Found my answer.
<form class="form-inline my-1 my-lg-0" action="{% url 'search_results' %}" method="get">
<input name="q" type="text" placeholder="Search" aria-label="Search">
<a class="btn btn-secondary my-2 my-sm-0" href='/gymapp/videos/' type=submit>Search</a>
</form>
I shouldn't have used an tag for the button. Changed it to tag and now the query is working.
silly mistake.

Is there a way for Link model to query in the Navbar Links of my Django project

I created a Link model in my django project that loads in as navigation links in my base.html file which is the template that is being inherited by the other html files.
I have tried the usual way or at least the way i was taught using Listview,{% for %}
def view_link(ListView):
context_object_name = 'links'
Model = Links
Class Link(Models):
link_name = models.CharField(max_length=265)
<nav class="navbar navbar-expand-lg">
<a class="navbar-brand">HOME</a>
<button class="navbar-toggler" data-toggle="collapse" data-target="#collapseMenu">
<span class="navbar-toggler-icon"></span>
</button>
<div class="navbar navbar-collapse">
<ul class="navbar-nav">
{% for link in links %}
<li class="nav-item"><a class="nav-link">{{ link.link_name}}</a></li>
{% endfor %}
</ul>
</div>
</nav>
I expect the to query the link_names i stored in my link model to query as links for my navigation bar but instead it returns blank but when i do it manually and add links one by one it shows all of the links
Can you please correct your model name in the view.
Model = Links
it should be Model = Link.
Thanks.

Resources