play <audio></audio> file in django template - django

I've been struggling with this for so long that I'm bordering depression.
I have a model called "Song" that looks like this.
from django.db import models
class Song(models.Model):
title = models.CharField(max_length=100)
songfile = models.FileField()
duration = models.FloatField()
isPlaying = False
def __str__(self):
return self.title
When you upload an mp3 file from the index page, it creates an instance of this model and stores the file in myapp/songdir/ using this view:
def home(request):
if request.method == 'POST':
form = UploadForm(request.POST, request.FILES)
if form.is_valid():
song_title = request.POST.items()[1][1]
song_address = 'upnplay/songdir/' + song_title + '.mp3'
with open(song_address, 'wb+' ) as destination:
for chunk in request.FILES['file'].chunks():
destination.write(chunk)
audio = MP3(song_address)
c = Song(title = song_title, songfile = song_address, duration = audio.info.length)
c.save()
return HttpResponseRedirect('')
else:
form = UploadForm()
c = {'form': form}
c.update(csrf(request))
return render(request, 'index.html', {'form': form})
Then I have a template called "choosesong" that displays a list of songs that I get from the model instances saved:
{% extends 'index.html' %}
{% block content %}
<div class="row">
{% for song in playlist %}
<h3>{{song.title}} -- {{song.duration}}</h3>
{% endfor %}
</div>
{% endblock %}
{% block form %}{% endblock %}
When I click on one of this links, I want a new template to be rendered, with a element that plays the song whose name I clicked. The template that I render is this one:
{% extends 'index.html' %}
{% block content %}
<div class='row'>
{{link}}
<audio controls>
<source src="../../{{ link }}" type="audio/mpeg">
Your browser does not support the audio element.
</audio>
</div>
{% endblock %}
And the view I use to deliver it is the following:
def playAudioFile(request, songtitle):
name = urllib.unquote(songtitle)
song = get_object_or_404(Song, title=name )
return render(request, 'playlist.html', {'link': song.songfile })
For some reason I can't get it to play the song inside the audio element and I don't know what else to try.
Thank you beforehand.

You should add MEDIA_ROOT and MEDIA_URL configuration. It will be easy to handle things. Here is the solution to your problem.
In settings.py:
MEDIA_ROOT=os.path.join(BASE_DIR,"songdir")
MEDIA_URL='/media/'
Also in settings.py add
'django.template.context_processors.media',
in the TEMPLATES option's context_processors.
In project/urls.py:
from django.conf import settings
from django.conf.urls.static import static
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Then you can simply use:
{{link.url}}
instead of hardcoding it in your template file.

Related

Can't get Django to upload files (UPDATE: SOLVED)

I have read many questions, followed the Django docs, googled for answers, and I can't get to upload a file in my Django app.
There is no error, form.cleaned_data shows the file and the other foreign key field, but no upload to media folder and no record in my db.
I can't figure what am I missing. Any help would be much appreciated.
#models.py
class ReportFile(models.Model):
report = models.ForeignKey(Report, on_delete=models.CASCADE)
file = models.FileField(upload_to='files/reports')
uploaded = models.DateTimeField(auto_now_add=True)
uploaded_by = models.ForeignKey(User, on_delete=models.CASCADE)
def save(self, *args, **kwargs):
user = get_current_user()
if user and not user.pk:
user = None
if not self.pk:
self.creado_por = user
###UPDATE: As Iain Shelvington kindly pointed out, I was missing the call to super.
super(ReportFile, self).save(*args, **kwargs)
#forms.py
class FileForm(forms.ModelForm):
class Meta:
model = ReportFile
fields = ['file','report']
This is the view I'm using, based on what I've read
#views.py
def CreateFile(request):
if request.method == 'POST':
form = FileForm(request.POST,request.FILES)
if form.is_valid():
form.save()
print(form.cleaned_data)
#OUTPUT: HTTP POST /file 200 [0.09, 127.0.0.1:59053]
# {'file': <InMemoryUploadedFile: test-image.png (image/png)>, 'report': <Report: 49>}
return render(request, 'segcom/file_upload.html', {'form': form,})
else:
form = FileForm()
context = {
'form':form,
}
return render(request, 'segcom/file_upload.html', context)
The relevant settings that I know of
#settings.py
# Media Root
MEDIA_ROOT = os.path.join(BASE_DIR, "media")
MEDIA_URL = '/media/'
This is the template I'm using
{% extends "layouts/base.html" %}
{% load crispy_forms_tags %}
{% block title %} File Upload Test {% endblock %}
<!-- Specific CSS goes HERE -->
{% block stylesheets %}{% endblock stylesheets %}
{% block content %}
<div class="row">
{{ form.non_field_errors }}
<form method = 'post' action="{% url 'file_upload' %}" id="report-form" enctype="multipart/form-data">
{% csrf_token %}
{{form|crispy}}
<div class="modal-footer">
<button type="submit" form="report-form" class="btn btn-primary">Guardar</button>
</div>
</form>
</div>
{% endblock content %}
<!-- Specific Page JS goes HERE -->
{% block javascripts %}
{% endblock javascripts %}

Django: Issue displaying updates for a MultipleChoiceField, template keeps displaying initial values

First post, apologies in advance for errors.
My problem:
I initialize my model fields from a proprietary db. These fields are displayed correctly in my template upon first display (I can see the html reflects the values in my proprietary db). I then change the initial selection options (for the MultiSelectField) in my template, and save these changed options to the Django db (verified its saved via the admin function) via post overloading in my views. My success_url is setup in urls.py to redisplay the same view. I have overloaded get_context_data in views to load the form data from the Django database, and to update context data with this loaded data, the idea being that when the templates redisplays (when selecting the submit_button), my html form should now displays the from data loaded from the Django db (not the initial values). What's happening, though, is that the initial values seems to be displayed, as opposed to the changed values I have loaded from the Django db. I would really appreciate help wrt understanding why the template displays values other than what I have loaded from the Django db. The form value that I update in my context before returning it in views.py is not what is displayed in the template.
my models.py:
class LiquidAssetModel(models.Model):
#Get my initial values from an external db
unq_assets = Jnance_base_data_main.get_unq_assets()
init_values = Jnance_base_data_main.get_liq_indexes()
liq_dates = Jnance_base_data_main.get_dates()
#initialize my fields
liquid_choices = MultiSelectField(choices = unq_assets, default = init_values)
from_date = models.CharField(max_length=200, choices=liq_dates, default=liq_dates[0][0])
to_date = models.CharField(max_length=200, choices=liq_dates, default=liq_dates[0][0])
def __str__(self):
return self.from_date
My froms.py:
class LiquidAssetsForm(forms.ModelForm):
# specify the name of model to use
class Meta:
model = LiquidAssetModel
fields = "__all__"
My post overload from views.py
def post(self, request, *args, **kwargs):
form_class = self.get_form_class()
form = self.get_form(form_class)
#form = forms.LiquidAssetsForm(request.POST)
#form.is_valid goes to the LiquidAssetsForm class and clean(self) overload to check whether the submitted data is fine
if form.is_valid():
liquid_indexes = form.cleaned_data.get('liquid_choices')
from_index = form.cleaned_data.get('from_date')
to_index = form.cleaned_data.get('to_date')
#cleare the database
all_forms = LiquidAssetModel.objects.all()
all_forms.delete()
form.save(commit=False)
form.save(commit=True)
#save our liquid asset choices to db
Jnance_base_data_main.put_liq(liquid_indexes)
#make sure the db is set up, copy the excel files, and then load them into the db
Jnance_base_data_main.gen_liq_graph(liquid_indexes, int(from_index), int(to_index))
return self.form_valid(form, **kwargs)
else:
return self.form_invalid(form, **kwargs)
my get_context_data overload from views.py:
class LiquidView(FormView):
template_name = 'liquid_chart.html'
form_class = forms.LiquidAssetsForm
success_url ="/thanksLiquid/"
liq_file_name = ''
def get_context_data(self, **kwargs):
context = super(LiquidView, self).get_context_data(**kwargs)
#build the string to search for a date_NAV file
search_str = settings.STATIC_ROOT + '/Jnance_Mainapp/images/date_liq*'
search_str = search_str.replace('\\', '/')
#search for a file
the_files = glob.glob(search_str)
#split the string and only use the part after 'static/', since we will use the static template tag in the html
if the_files:
#just use the very first file we found in the list
self.liq_file_name = the_files[0].split('static/')[1]
self.liq_file_name = self.liq_file_name.replace('\\', '/')
else:
print("Jnance_Mainapp: views LiquidView no liquid chart found to display")
#update our context with the file name
context.update({'liquid_file_name': self.liq_file_name})
form_class = self.get_form_class()
form = self.get_form(form_class)
the_obj = LiquidAssetModel.objects.all()
if len(the_obj) == 0:
#no forms saved yet
pass
else:
form.liquid_choices = the_obj.values('liquid_choices')[0]
form.from_date = the_obj.values('from_date')[0]
form.to_date = the_obj.values('to_date')[0]
print (form.liquid_choices)
context.update({'form': form})
return context
my urls.py:
urlpatterns = [
path('', views.HomeView.as_view(), name='home'),
path('NAV_Charts/', views.NAVView.as_view(), name='NAV_Charts'),
path('Asset_Charts/', views.AssetView.as_view(), name='Asset_Charts'),
path('Liquid_Charts/', views.LiquidView.as_view(), name='Liquid_Charts'),
path('Sum_Charts/', views.SumView.as_view(), name='Sum_Charts'),
path('Base_Load/', views.BaseLoadView.as_view(), name='Base_Load'),
path('admin/', admin.site.urls, name= 'admin'),
path('thanksNAV/', views.NAVView.as_view()),
path('thanksAsset/', views.AssetView.as_view()),
path('thanksLiquid/', views.LiquidView.as_view()),
path('thanksBaseLoadForm/', views.BaseLoadView.as_view()),
path('Jnance_Mainapp/', include('Jnance_Mainapp.urls', namespace='Jnance_Mainapp')),]
my template:
{% extends "base.html" %}
{% load static %}
{% load crispy_forms_tags %}
{% block body_block %}
<h1 class="text-center display-1" Bootstrap heading (2.5rem = 40px)>Jnance Liquid Assets Chart Generation</h1>
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
<table class="row">
<div class="row">
<div class="col-sm-6 text-center align-left">
<img class="img-fluid mb-1" src="{% static liquid_file_name %}" alt="Unable to load chart!"/>
</div>
<br>
<div class="col-sm-3 text-left align-left">
{{ form.from_date|as_crispy_field }}
<br>
{{ form.to_date|as_crispy_field }}
<br>
<br>
<input name="submit_button" type="submit" value="Generate" id="update_button"
class="btn btn-success" enctype="multipart/form-data">
</div>
<div class="col-sm-3 text-left align-left">
{{ form.liquid_choices|as_crispy_field }}
</div>
</div>
</table>
</form>
{% endblock %}
Your setting the initial values to whatever the first object is that gets returned in the_obj = LiquidAssetModel.objects.all() when you set them with the_obj.values('liquid_choices')[0]

Django Search Implementation, conditional routing

I am trying to implement basic search functionality with Django. Could use help with accessing query inputs from forms in templates in functional or class based views. Intended functionality:
If exact search query page exists, display that page
If there is a page title that contains what was queried, show results of all
If neither, display a message stating no results found
I'm just learning, so I tried functional views and class based views. I've spent a really long time on documentation/videos/textbooks and don't see how to get the intended behavior out of class-based view. I understand collecting object_list and getting query_set, but how do you then route to those three different conditions. I tried overriding dispatch() and as_views() method to no avail. Tried with a Django form class and without.
For some reason, the functional view keeps executing the first try statement instead of throwing a DoesNotExist exception when the exact match isn't found. So it shows the entry page instead of the search results page. It seems like the request.GET is None type no matter what, as when I try to print nothing shows up.
urls.py
from re import search
from django.urls import path
from . import views
from .views import IndexPageView, SearchView
app_name = "wiki"
urlpatterns = [
# ex: /wiki/
path("", views.index, name="index"),
# path("", IndexPageView.as_view(), name="index"),
# ex: /wiki/EntryPageName
path("wiki/<str:entry>/", views.displayEntry, name="displayEntry"),
# path("wiki/search/", views.searchView, name="searchView")
path("wiki/search/", SearchView.as_view(), name="searchView")
]
model
class Entry(models.Model):
title = models.CharField(max_length=64)
def __str__(self):
return f"{self.title}"
content = models.TextField()
views.py
def searchView(request):
searchedTerm = request.GET.get('q')
try:
exactMatch = Entry.objects.get(title=searchedTerm)
entryTitle = exactMatch.title
entryHTML = markdown2.markdown(exactMatch.content)
return render(request, "encyclopedia/displayEntry.html", {
"entryTitle": entryTitle,
"entryHTML": entryHTML
})
except:
try:
searchResults = Entry.objects.filter(Q(title__icontains=searchedTerm))
return render(request, "encyclopedia/searchResults.html", {
"searchResults": searchResults,
"searchedTerm": searchedTerm
})
except:
return render(request, "encyclopedia/searchResults.html", {
"emptyResults": f"No entries found matching: {searchedTerm}",
"searchedTerm": searchedTerm
})
class SearchView(ListView):
template_name = "encyclopedia/searchResults.html"
model = Entry
context_object_name = "searchList"
def get_queryset(self):
searchedTerm = self.request.GET.get('q')
try:
searchResults = Entry.objects.get(title=searchedTerm)
return searchResults
except:
try:
searchResults = Entry.objects.filter(Q(title__icontains=searchedTerm))
return searchResults
except:
pass
def as_view():
searchedTerm = self.request.GET.get('q')
try:
exactMatch = Entry.objects.get(title=searchedTerm)
entryTitle = exactMatch.title
entryHTML = markdown2.markdown(exactMatch.content)
return render(request, "encyclopedia/displayEntry.html", {
"entryTitle": entryTitle,
"entryHTML": entryHTML,
})
except:
searchResults = Entry.objects.filter(Q(title__icontains=searchedTerm))
return render(request, "encyclopedia/searchResults.html", {
"searchResults": searchResults,
"searchedTerm": searchedTerm
})
else:
return render(request, "encyclopedia/searchResults.html", {
"emptyResults": f"No entries found matching: {searchedTerm}",
"searchedTerm": searchedTerm
})
search form from layout.html
<form action="{% url 'wiki:search' %}" method="GET">
<input class="search" type="text" name="q" placeholder="Search Encyclopedia">
<!-- <input type="submit" value="submit"> -->
</form>
display entry page template
{% extends "encyclopedia/layout.html" %}
{% block title %}
{% if entryTitle %}
{{ entryTitle }}
{% else %}
Page Not Found!
{% endif %}
{% endblock %}
{% block body %}
{% if entryHTML %}
{{ entryHTML|safe }}
{% else %}
<p>This page does not exist yet.</p>
<p>Check your spelling or create a new entry!</p>
<p>?? {{ testPrint }}</p>
{% endif %}
{% endblock %}
search results page
{% extends "encyclopedia/layout.html" %}
{% block title %}
Search Results: {{ searchedTerm }}
{% endblock %}
{% block body %}
{% if searchResults %}
<h3>Search Results</h3>
<ul>
{% for result in searchResults %}
<li>{{ result.title }}</li>
{% endfor %}
</ul>
{% else %}
<h3>{{ emptyResults }}</h3>
{% endif %}
{% endblock %}
Models
class Entry(models.Model):
title = models.CharField(max_length=64)
content = models.TextField()
def __str__(self):
return self.title
Views
from django.views.generic.list import ListView
from django.views.generic.detail import DetailView
from app.models import Entry
class EntryListView(ListView):
model = Entry
paginate_by = 100 # if pagination is desired
def get_queryset(self):
queryset = super().get_queryset()
q = self.request.GET.get("q")
if q:
queryset = queryset.filter(title__icontains=q)
return queryset
class EntryDetailView(DetailView):
model = Entry
Urls
from django.urls import path
from app.views import EntryListView, EntryDetailView
urlpatterns = [
path('', EntryListView.as_view(), name='entry-list'),
path('<int:pk>/', ArticleDetailView.as_view(), name='entry-detail'),
]

Rendering the page in django with html form

I have these two functions, one of them (first one) adds a new entry and the second one edits the entry:
def add_entry(request):
if request.method == 'POST':
form = AddForm(request.POST)
if form.is_valid():
title = form.cleaned_data["title"]
content = form.cleaned_data["content"]
if util.get_entry(title) is None:
util.save_entry(title, content)
return redirect('entry', title)
else:
return render(request, "encyclopedia/add_entry.html", {
"form": AddForm(),
"title": title
})
return render(request, "encyclopedia/add_entry.html", {
"form": AddForm()
})
def edit_entry(request, title):
content = util.get_entry(title)
if request.method == 'POST':
form = AddForm(request.POST)
if form.is_valid():
title = form.cleaned_data["title"]
content = form.cleaned_data["content"]
util.save_entry(title, content)
return redirect('entry', title)
return render(request, "encyclopedia/edit_entry.html", {
"title": title,
"content": content
Here is my edit_entry.html page:
{% extends "encyclopedia/layout.html" %}
{% block title %}
Edit page
{% endblock %}
{% block body %}
<form action="{% url 'edit_entry' title %}" method="POST">
{% csrf_token %}
<h5>Title</h5>
<input type="text" value="{{ title }}">
<h5>Content</h5>
<textarea cols="30" rows="10">{{ content }}</textarea>
<input type="submit" value="Save Editing">
</form>
{% endblock %}
This is add_entry.html template
{% extends "encyclopedia/layout.html" %}
{% block title %}
Add new entry
{% endblock %}
{% block body %}
<h1>Create a new page</h1>
{% if title %}
<h6 style="color: red;">"{{title}}" page is already exists. Please, enter a different title</h6>
{% endif %}
<form action="{% url 'add_entry' %}" method="POST">
{% csrf_token %}
{{ form }}
<input type="submit" value="Create">
</form>
{% endblock %}
And here is my urls.py:
from django.urls import path
from . import views
urlpatterns = [
path("", views.index, name="index"),
path("wiki/<str:title>", views.entry, name="entry"),
path("search", views.search, name="search"),
path("add_entry", views.add_entry, name="add_entry"),
path("wiki/<str:title>/edit_entry", views.edit_entry, name="edit_entry")
]
My entry view:
def entry(request, title):
if title not in util.list_entries():
return render(request, "encyclopedia/error.html", {
"error": "Page Not Found",
"query": title
})
else:
return render(request, "encyclopedia/entry.html", {
"entry": markdown2.markdown(util.get_entry(title)),
"title": title
})
The issue here when I click to save the content of the page doesn't change, I want to save the edits and display it with new content. Instead, it returns an old form with the old content (like doesn't change).
EDIT: based on your comments, I think it is better to start over.
Since you are doing some simple create and update, it maybe better to use generic views. Here is an example.
1.First and formost, you need a model.
in models.py,
from django.db import models
class Entry(models.Model):
title = models.CharField(max_length=200)
content = models.TextField(max_length=2000)
2. in your forms.py
Note: this is not necessary if you want to just use django default form. Because class-based generic views will automatically generate forms for you. However, if you need to add widget, or to add attributes (for example, add css class or id), you need to generate a customform.
from django import forms
from .models import Entry
class EntryForm(forms.ModelForm):
class Meta:
model = Entry
fields = ('title', 'content')
widgets = {
'title': forms.TextInput(attrs={'placeholder': 'Title'}),
'content': forms.TextInput(attrs={'class': 'content'}),
}
3. views.py
from .models import Entry
from django.views.generic.edit import CreateView, UpdateView
class CreateEntry(CreateView):
model=Entry
template_name = 'create_edit_entry.html' # this is the template, you might need to change its path.
form_class= EntryForm # this is added because we are using customform
success_url = '/' #this can be changed
class UpdateEntry(UpdateView):
model=Entry
template_name = 'create_edit_entry.html'
form_class= EntryForm
4. urls.py
from django.urls import path
from .views import CreateEntry, UpdateEntry
urlpatterns = [
path('entry/', CreateEntry.as_view(), name='create_entry'),
path('entry/<int:pk>', UpdateEntry.as_view(), name='update_entry'),
]
5. admins.py
from django.contrib import admin
from .models import Entry
class EntryAdmin(admin.ModelAdmin):
list_display = (('id', 'title', 'content'))
admin.site.register(Entry, EntryAdmin)
6. templates (create_edit_entry.html)
{% extends 'base.html' %}
{% block extrahead %}
{% load static %}
{% endblock %}
{% block content %}
<form action="." method="POST">
{% csrf_token %}
{{ form }}
<button type="submit">SUBMIT</button>
</form>
{% endblock %}
After you update all these files and update mysite/urls.py, you will 1) open http://127.0.0.1:8000/entry to add an entry. Check if the entry is created in your admin page. 2) then you will open http://127.0.0.1:8000/entry/1 (if the id=1) to see if your original entry is shown. 3) then you will update the form, and check if the update is successful or not in your admin.
This backbone should be able to get you started. Note that I did not put DetailView, ListView, so you need to check if the object is created and updated in your admin page. Of cause, you can add DetailView and ListView by yourself (check out django document here to learn more about generic views).
**************************************earlier answer **************
1. First thing first, it is always helpful to access form.errors when you are having trouble with forms. What you do is to add else: print(form.errors) like the following:
if form.is_valid():
# other code
else:
print(form.errors)
2.
Your edit_entry.html change to something like below: I guess you wanted use your own styling (add Title, Content etc) to the form, so you did not use {{form}}. If what I suggest worked, you can add form styling later.
{% extends "encyclopedia/layout.html" %}
{% block title %}
Edit page
{% endblock %}
{% block body %}
<form action="{% url 'edit_entry' title %}" method="POST">
{% csrf_token %}
{{form}}
</form>
{% endblock %}
3. your edit_entry view:
def edit_entry(request, title):
entry = get_object_or_404(Entry, title=title) # i assume your Model name is "Entry"
if request.method == 'POST':
form = AddForm(request.POST, instance = entry)
if form.is_valid():
print('under form.is_valid) # add this line to keep track
title = form.cleaned_data["title"]
content = form.cleaned_data["content"]
form.save()
return redirect('entry', title=entry.title)
else:
print(form.errors)
else:
form = AddForm(instance = entry)
return render(request, "encyclopedia/edit_entry.html", {
'form': form})

How do I display the result of the beautifulsoup4 parser in django templates?

I'm working on a web application that collects jobs for programmers. It uses django 2.2 and beautifulsoup4.
I try to display the results of parsing on the screen after clicking the button in the form redirects to the page of the result of parsing (None). There may be an error in parser or views.py, I can't figure it out.
Logic:
1. Django displays the form on the main page
2. The user presses the button in the form
3. Parser collects data
4. Parsing result is displayed on the screen
workua.py - scraper
import requests
from bs4 import BeautifulSoup
def clean_description(s):
return s.split('\n')[1]
def get_html(url):
r = requests.get(url)
return r.text
def get_data(html):
bs = BeautifulSoup(html, 'lxml')
job_list = bs.find('div', id='pjax-job-list').find_all('div', class_='card card-hover card-visited wordwrap job-link')
for item in job_list:
title = item.find('h2', class_='add-bottom-sm').text
company = item.find('b').text
d = item.find('p', class_='overflow').text
descr = clean_description(d)
url = 'https://www.work.ua' + item.find('h2', class_='add-bottom-sm').find('a').get('href')
data = {'title':title, 'company':company, 'descr':descr, 'url':url}
# print(data)
def main():
pattern = 'https://www.work.ua/ru/jobs-kyiv-python/?page={}'
for i in range(0, 3):
url = pattern.format(str(i))
get_data(get_html(url))
views.py
from django.shortcuts import render
from .workua import *
from .forms import PageForm
def index_page(request):
form = PageForm(request.GET)
return render(request, 'page/index_page_form.html', context={'form':form})
def workua_result(request):
result = main()
return render(request, 'page/workua_result.html', context={'result':result})
index_page_form.html
{% extends 'base.html' %}
{% block title %}
Main page
{% endblock %}
{% block content %}
<form action="{% url 'workua_result_url' %}" method="GET" class="mt-5 mb-
5 text-center">
{% csrf_token %}
{{ form }}
<button class="btn btn-primary mt-3" type="submit">Go</button>
</form>
{% endblock %}
urls.py
from django.urls import path
from .views import *
urlpatterns = [
path('', index_page, name='index_page_url'),
path('workua/', workua_result, name='workua_result_url'),
]
workua_result.html
{% extends 'base.html' %}
{% block title %}
Work.ua result
{% endblock %}
{% block content %}
{{ result }}
{% endblock %}
Wrote a parser in views.py and the problem is solved.
Created an empty data list and added the data that I collected from beautifulsoup. Before rendering called the main() function and passed the list of data in the context.
views.py
def workua_result(request):
data = []
def get_html(url):
r = requests.get(url)
return r.text
def get_data(html):
bs = BeautifulSoup(html, 'lxml')
job_list = bs.find('div', id='pjax-job-list').find_all('div', class_='card card-hover card-visited wordwrap job-link')
for item in job_list:
try:
title = item.find('h2', class_='add-bottom-sm').text
company = item.find('b').text
descr = item.find('p', class_='overflow').text
url = 'https://www.work.ua' + item.find('h2', class_='add-bottom-sm').find('a').get('href')
data.append({'title': title, 'company': company, 'descr': descr, 'url': url})
except:
pass
def main():
pattern = 'https://www.work.ua/ru/jobs-kyiv-python/?page={}'
for i in range(0, 4):
url = pattern.format(str(i))
get_data(get_html(url))
main()
return render(request, 'page/workua_result.html', context={'data': data})