Django: Images/Absolute URLS from not displaying in html - python

I have a block of code on my template which does not show up on my html nor does it give any error on Chromes console. I am trying to display a list of images which when clicked takes you to the detail of that image.
Here is the key part of my HTML(base.html):
<div class="container-fluid">
<h2>Popular</h2> #only this shows up
{% for obj in object_list %}
<img src = "{{ obj.mpost.url}}" width="300"><br>
<a href='/m/{{ obj.id }}/'> {{obj.username}} </a><br/>
{% endfor %}
</div>
views.py:
from django.shortcuts import render,get_object_or_404
from .models import m
# Create your views here.
def home(request):
return render(request,"base.html",{})
def m_detail(request,id=None):
instance = get_object_or_404(m,id=id)
context = {
"mpost": instance.mpost,
"instance": instance
}
return render(request,"m_detail.html",context)
def meme_list(request): #list items not showing
queryset = m.objects.all()
context = {
"object_list": queryset,
}
return render(request, "base.html", context)
urls.py:
urlpatterns = [
url(r'^$', home, name='home'),
url(r'^m/(?P<id>\d+)/$', m_detail, name='detail'),#issue or not?
]
models.py:
class m(models.Model):
username = "anonymous"
mpost = models.ImageField(upload_to='anon_m')
creation_date = models.DateTimeField(auto_now_add=True)
def __str__(self):
return m.username
Thank you so much for your time. :)

I assume the problem is the fact that you don't have a url at all for the meme list, so either you're showing the home view and need to move the code from the meme_list view into your home view, or you need to make a url for the meme_list (and navigate to that new url instead)

Related

Class based views does not render HTML in template-Is context missing?

I started to work with class based views, but the codes that I've written initially does not render in the template when I use class based views. The data that is in note.title (see template) simply does not show up when I use class based views.
When I change back to function based views and refresh the page, the HTML code in the template shows up without any problems. Could someone explain what causes this error?
I've read something about context not been found by the template but I don't really understand what it means and how context resolves the issue.
Thanks in advance!
views.py
from multiprocessing import context
from django.shortcuts import render
import notes
from .models import Notes
from django.http import Http404
from django.views.generic import ListView, DetailView, CreateView
# Create your views here.
class NotesCreateView(CreateView):
models = Notes
fields = ["title", "text"]
succes_url = "/smart/notes"
class NotesListView(ListView):
model = Notes
context_objects_name = "note"
template_name = "notes/notes_list.html"
class NotesDetailView(DetailView):
model = Notes
context_object_name = "note"
# def list(request):
# all_notes = Notes.objects.all()
# context = {'notes': all_notes}
# return render(request, 'notes/notes_list.html', context)
# def detail(request, pk):
# try:
# note = Notes.objects.get(pk=pk)
# except Notes.DoesNotExist:
# raise Http404("This note doesn't exist")
# context = {'note': note}
# return render(request, 'notes/notes_detail.html', context)
urls.py
from django.urls import path
from . import views
app_name = "notesApp"
urlpatterns = [
path('notes', views.NotesListView.as_view(), name="notes.list"),
path('notes/<int:pk>', views.NotesDetailView.as_view(), name="notes.deta"),
path("notes/new", views.NotesCreateView.as_view(), name="notes.view"),
# path('notes', views.list, name="notes.list"),
# path('notes/<int:pk>', views.detail, name="notes.deta"),
]
template
{% extends 'base.html' %}
{% block content %}
<h1 class="my-5">This are the notes:</h1>
<div class="row row-cols3 g-2">
{% for note in notes %}
<div class="col">
<div class="p-3 border">
<a href="{% url 'notesApp:notes.deta' pk=note.id %}" class="text-dark text-decoration-non">
<h3>{{notes.title}}</h3>
</a>
{{note.text|truncatechars:10}}
</div>
</div>
{% endfor %}
</div>
{% endblock %}
You have to use precisely what you set in context_objects_name. So if you want to loop through Notes objects in ListView, then you have to set your view to:
class NotesListView(ListView):
model = Notes
context_objects_name = "notes" # PLURAL
Then in template leave everything as is. Well, maybe you want to change {{notes.title}} to {{note.title}}, because it is inside the for loop.

Django form not rendering? (No Model)

So my Django form is not rendering in the html.
all I'm able to see is the Get Rank text.
I'm not sure if it's because I don't have a model or maybe it's something wrong with my html?
If you need to see anything else let me know not sure what's wrong, I also tried just doing it all inside of the home function but then it doesn't render the html at all.
Side question - Also I only plan on grabbing the users name, and the tag outside their name ("JohnDoeNA#1") so I probably use a get method correct?
EDIT: Fixed the button not working now only thing not rendering is the form. (Mis-spelling)
Updated Code to be correct.
views.py:
from urllib import response
from django.shortcuts import render
from django.http import HttpResponse
import requests
from .forms import SearchUser
import json
# Create your views here.
def index(response):
return render(response, "main/base.html")
def home(response):
form = SearchUser()
data = requests.get(
'https://americas.api.riotgames.com/riot/account/v1/accounts/by-riot-id/ReallyBlue/NA1?api_key=RGAPI-ee8fcdce-05c5-4ad4-b909-8efa722b1134')
userid = data.json()['puuid']
return render(response, "main/home.html", {
'form': form,
'userid': userid,
# 'mmr': apidata['rank']
})
forms.py:
from django import forms
class SearchUser(forms.Form):
name = forms.CharField(label="Name", max_length=200)
urls.py:
from django.urls import path
from . import views
urlpatterns = [
path("", views.index, name="index"),
path("home/", views.home, name="home")
]
home.html:
{% extends 'main/base.html'%}
{% block content %}
<h2>Valorant Ranked Checker</h2>
<form method="post" action="/home/">
{{form}}
<button type="submit", name="search">
Get rank
</button>
</form>
<p><strong>{{userid}} - {{mmr}}</strong></p>
{% endblock %}
base.html:
<!DOCTYPE html>
<head>
<title>Blue's Valorant Ranked Checker</title>
</head>
<body>
<div id="content", name="content">
{% block content %}
{% endblock %}
</div>
</body>
</html>
You have two main issues here:
You were rendering your base template as your root directory (base.html) and therefore Django's template inheritance wasn't working correctly. You'll want to render the child template (the one that includes extends) if you want template inheritance to work properly.
You need to pass your Django form (SearchUser) to the render function of the view
I recommend making these changes:
====================
Remove reference to the index view in your urls.py as we don't need it. Instead, use your home child template as your root view:
urls.py:
from django.urls import path
from . import views
urlpatterns = [
path("", views.home, name="home")
]
====================
Remove the no longer needed index function from views.py. You'll also want to pass reference to your form (SearchForm) inside of Django's render shortcut function.
views.py:
from urllib import response
from django.shortcuts import render
from django.http import HttpResponse
import requests
from .forms import SearchUser
import json
# Create your views here.
def home(response):
data = requests.get(
'https://americas.api.riotgames.com/riot/account/v1/accounts/by-riot-id/ReallyBlue/NA1?api_key=RGAPI-APIKEY')
userid = data.json()['puuid']
return render(response, "main/home.html", {
'form': SearchUser(), # include reference to your form
'userid': userid,
# 'mmr': apidata['rank']
})
def search(response):
form = SearchUser()
return render(response, "main/home.html", {"form": form})
Your view function that renders the form and the form template must match. form also must be in your context.
Put the form in the home.html and change the home view like so:
def home(response):
form = SearchUser()
return render(response, "main/home.html", {'form': form})

How can i call class function thats insert row into db properly from my django template?

Hellow, I am noob and I make instagram followers scraper on Django.
I make a function that should add 1 (only 1 cos it works really slow) new follower in to db which takes from already working sсraping functions and place it into class.
class ListOfFollowers(ListView):
model = Followers
context_object_name = 'followers_of'
template_name = 'insta/followers.html'
def get_follower(self, username):
loader = instaloader.Instaloader()
loader.login('***', '***')
profile = instaloader.Profile.from_username(loader.context, username)
followers = profile.get_followers()
followers_tuple = tuple(followers)
i = random.randint(0, len(followers_tuple) - 1)
login = followers_tuple[i].username
photo = followers_tuple[i].get_profile_pic_url()
url = f'https://www.instagram.com/{login}/'
mutual_subscription = followers_tuple[i] in profile.get_followees()
res = {'login': login, 'photo': photo, 'url': url, 'mutual_subscription': mutual_subscription}
return res
def add_followers(self):
username = WhoFollow.objects.get(follow_on__contains=self.kwargs['follow_id']).title
context = None
while not context:
try:
context = get_follower(username)
except:
next
context.update({'follow_on': self.kwargs['follow_id']})
res = Followers(context)
res.save()
def get_queryset(self):
return Followers.objects.filter(follow_on=self.kwargs['follow_id'])
function calls add_followers (try block is just because its not always working from 1st try)
My models
class WhoFollow(models.Model):
title = models.CharField(max_length=255)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('follow', kwargs={'follow_id': self.pk})
class Followers(models.Model):
login = models.CharField(max_length=255)
photo = models.ImageField(upload_to="photos/", blank=True)
url = models.URLField()
mutual_subscription = models.BooleanField(default=False)
time_add = models.DateTimeField(auto_now_add=True)
time_unfollow = models.DateTimeField(blank=True)
follow_on = models.ForeignKey(WhoFollow, on_delete=models.PROTECT)
def __str__(self):
return self.login
And my template
{% extends 'insta/Base.html' %}
{% block content %}
<h1>Who we find</h1>
<ul>
{% for l in object_list %}
<li>
<h5>{{l.login}}</h5>
</li>
{% endfor %}
</ul>
<!-- from there i dont understand what i should do too -->
<form action="{% url views.ListOfFollowers.}">
<button type="submit" onclick="">add another 1</button>
</form>
{% endblock %}
urls.py
urlpatterns = [
path('admin/', admin.site.urls),
path('', Home.as_view(), name='home'),
path('add/', AddWhoFollow.as_view(), name='add'),
path('follow/<int:follow_id>', ListOfFollowers.as_view(), name='follow'),]
Sorry for too many code but my head already broken on this task.
There are some issues with your code:
First, you have added the two methods get_follower() and add_followers() to the your ListView, but it is unclear how (if at all) they are called. It looks to me like you might be misunderstanding the concept of the ListView. The purpose of the ListView is to render a list of objects, not add something. So instead you want to create a new view for adding followers. You can just define a simple function view for that, does not have to be a CBV.
Second, each view needs to have it's own URL defined. You did not post your urls.py, but I suppose {% url views.ListOfFollowers.} in the template will not work. Instead, you need to define a URL name in your urls.py (one for each view) and out that in your template.
I was totaly misunderstand the concept of the CBV.
The answer is that i should do it inside CreateVeiw after form validation where i choose which login to scrap.
There is result:
class AddFollowers(CreateView):
form_class = AddFollower
model = Followers
template_name = 'insta/add_follower.html'
def get_success_url(self):
return reverse_lazy('home')
def form_valid(self, form):
# Here is a body of scraping script where i creating a list of objects to add in db
Followers.objects.bulk_create(objs=res)
return HttpResponseRedirect(f'http://127.0.0.1:8000/)

How does one pass arguments from the URL to a view before rendering a new page?

I am creating a stock portfolio app. The user has a list of stocks each of which has a link which looks something like 'http://127.0.0.1:8000/search/symbol=TSLA'. What I want to do is pass the stock symbol 'TSLA' to one of my views and simply print that string on the next page (for now).
What I have done so far (did not include it in the code below) is to simply have some method in my SearchPageView called get_symbol and I tried to get the url from there and in my search.html template, I tried accessing that via {{ view.get_symbol }}. But this displays nothing.
My set-up:
views.py:
class SearchPageView(TemplateView):
template_name = 'search.html'
urls.py:
from django.urls import path, re_path
from .views import SearchPageView
urlpatterns = [
path('search/<string>', SearchPageView.as_view(), name='search_stock'),
]
search.html:
{% extends 'base.html' %}
{% block content %}
{% endblock content %}
I know there's nothing above, all i'm asking for is how to pass the string 'TSLA' to my view then to 'search.html' then I can do what I need to do with it. I appreciate any help.
Change your urls.py by this
path('search/<symbol>', SearchPageView.as_view(), name='search_stock'),
In views.py
from django.shortcuts import get_object_or_404
from django.views.generic import ListView
class SearchPageView(ListView):
template_name = 'your_template.html'
def get_queryset(self):
self.publisher = get_object_or_404(YOUR_MODEL_NAME, name=self.kwargs['symbol'])
return YOUR_MODEL_NAME.objects.filter(symbol=self.symbol)
I consider your model field name is symbol.
You can try like this:
from django.shortcuts import render
def page_view(request):
# recheck how to get data you want pass in html from this view
return render(request, 'search.html', {
'symbol': request.DATA.get('symbol'),
})
and in url change to this:
urlpatterns = [
path('search/<string>', page_view, name='search_stock'),
]
and in search.html you will have {{ symbol }} variable from def page_view

Form not Displaying fields (Not seeing a forms.Forms object) - Django 1.11.8

I am trying to display a simple form (3 fields) on a webpage using Django but no fields are displaying - see code below.
I've gone through the Django doc, MDN doc, most of the StackOverflow posts here, but it's still not working.
I was able to see, using {% debug %}, that there is no object EmailInput on the page.
At this point, I am not sure what is causing this issue. Any help would be very much appreciated.
Thanks
forms.py
from django import forms
class EmailInput(forms.Form):
email = forms.EmailField()
first_name = forms.CharField()
last_name = forms.CharField()
views.py
from django.shortcuts import render
from .models import journalEntry
from django.http import HttpResponseRedirect
from django.urls import reverse
from journal.forms import EmailInput
def index(request):
post = journalEntry.objects.filter(status__exact='f')
latest_post = journalEntry.objects.filter(status__exact='f').order_by('-created')[:5]
return render(request, 'journal_index.html', context = {'post':post,'latest_post':latest_post})
def email_input(request):
if request.method == 'POST':
form = EmailInput(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect(reverse('journal-index'))
else:
form = EmailInput()
return render(request, 'journal_index.html',{'form':form})
journal_index.html
{% extends "base_generic.html" %}
{% block content %}
<form action="" method="post">
{% csrf_token %}
{{ form }}
<input type="submit" value="Submit"/>
</form>
{% endblock content %}
urls.py
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.index, name='journal-index'),
]
If you want to display it in the index page then you have to send it as a context variable in your index function. And now it will be available in your journal_index.html template file.
def index(request):
post = journalEntry.objects.filter(status__exact='f')
latest_post = journalEntry.objects.filter(status__exact='f').order_by('-created')[:5]
form = EmailInput()
context = {
'post': post,
'latest_post': latest_post,
'form': form
}
return render(request, 'journal_index.html', context = context)
The code from your email_input function is not called anywhere so there is no way this form could be displayed. Also you have to figure out where do you want to display this form. If you don't want to display it together with the stuff from your index page then you would have to create a new template file, add the form there and add a new url path to display that page.
It is because you are not even calling email_input.
you need to bind it to a url like this
urlpatterns = [
url(r'^$', views.email_input),
]

Categories

Resources