django ckeditor - call data from rich text editor - python

Does anyone know if it is possible to call data from the richtext editor in the admin panel?
My views.py looks like this:
def post_detail(request, slug):
posting = post.objects.get(slug=slug)
try:
if posting.slug == 'dividend_stocks_list':
data = pd.DataFrame(stocks(request))
allData=[]
for i in range(data.shape[0]):
temp = data.iloc[i]
allData.append(dict(temp))
context_posting = {
'title': posting.title,
'date': posting.date_added,
'intro': posting.intro,
'body': posting.body,
'data': allData
}
except:
context_posting = {
'title': posting.title,
'date': posting.date_added,
'intro': posting.intro,
'body': posting.body,
}
return render(request, 'post_detail.html', context_posting)
next is the html
{% block content %}
{% load humanize %}
<h1 class="title">{{ title }}</h1>
<small>Posted at {{ date }}</small>
<br/>
<br/>
<hr/>
<div>{{ intro | safe }}</div>
<hr/>
<div>{{ body | safe }}</div>
{% endblock %}
{% block js %}
{% endblock %}
I would like to type in the rich text editor
blablabla
{{ data | safe }}
blablabla
But till now I have not figured out how to do that.
Do you have any idea?

Related

Elasticsearch Python Django: How to limit the output text content and highlight the input keyword

This is my search function in views.py
def search(request, pk, slug):
es = Elasticsearch()
es_client = Elasticsearch(['http://127.0.0.1:9200'])
print('called search')
search_text = request.GET.get('qq')
print('Search text: {}'.format(search_text))
print('cluster id/ ealstic search index: {}'.format(pk))
s = None
count = 0
try:
if search_text:
s = Search(index=str(pk)).using(es_client).query("match", content=search_text)
response = s.execute()
count = 0
for hit in s:
count += 1
print(str(count) + ' - ' + str(hit.currnet_url))
#print(hit.content)
else:
print('nothing more found')
else:
print('No text to search')
except Exception as e:
count = 0
print('Exception caught')
msg = 'Cluster is not ready to be searched'
return render(request, 'base_app/cluster_search.html', {'warning':msg, 'count':count})
return render(request, 'base_app/cluster_search.html', {'cluster':slug, 'hits':s, 'count':count})
This is how I am indexing data to Elasticsearch.
def elastic_indexer(text, depth, url, clusrer_id):
es_client = Elasticsearch(['http://127.0.0.1:9200'])
doc = {
"date": time.strftime("%Y-%m-%d"),
"currnet_url": url,
"depth": depth,
"content": text
}
res = es_client.index(index= str(clusrer_id), doc_type="_doc", body=doc)
print(res["result"])
This is the frontend template where the users input a text to search.
{% extends "account/base.html" %}
{% load i18n %}
{% load crispy_forms_tags %}
{% block head_title %}{% trans "Search" %}{% endblock %}
{% block content %}
Go Back
<P style="font-size:17px;">You are searching in {{cluster.title}}</P>
<form method="GET" action="">
{% csrf_token %}
<button class="btn btn-primary" action="">Search</button>
<input id="q" name="qq" type="text" placeholder="enter search text here" style="width: 500px;">
</form>
{% if hits %}
<table>
{% for hit in hits %}
<tr>
<td>Hit: {{hit.currnet_url}}</td>
</tr>
<tr>
<td>Content: {{hit.content}}</a></td>
</tr>
{% empty %}
<h3> No search result found </h3>
{% endfor %}
</table>
{% endif %}
<div class="pagination">
<span class="step-links">
{% if page_obj.has_previous %}
« first
previous
{% endif %}
<span class="current">
Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.
</span>
{% if page_obj.has_next %}
next
last »
{% endif %}
</span>
</div>
{% endblock %}
This is returning everything, all the text stored in "content", how do I limit this to only the user's input text and only show limited characters before and after the input text? and including highlighting the input text? Please help me out
Example:
What it shows:
*User inputs text, assuming it's "django"*
hits: https://www.djangoproject.com/
Content: all of the scraped text stored in "content"
What I want it to show:
User inputs text, assuming it's "django"
hits: https://www.djangoproject.com/
Content: 10 words before "django" and 10 words after "django"

How to create a Class Based Views search bar on Django

I'm making a search bar in Django using Class-Based Views on my Views.py. When I try to get the value submitted in the input it's not showing the query name and if I don't submit anything is NOT giving me an error. Also what is the way to get the post showed by the world searched? Thanks for all. My code is:
Models.py:
class Post(models.Model): # Post core
title = models.CharField(max_length=299)
author = models.ForeignKey(User,default=ANONYMOUS_USER_ID, on_delete=models.CASCADE)
category = models.CharField(max_length=50)
image = models.ImageField(blank=True)
desc = models.TextField()
text = RichTextField(blank = True, null = True )
date = models.DateTimeField(auto_now=False, auto_now_add=True)
slug = models.SlugField(null = True, blank = True, unique=True)
class Meta: # Order post by date
ordering = ['-date',]
def __str__(self): # Display title
return self.title
def get_absolute_url(self): # #TODO da cambiare
return reverse("listpost")
Views.py:
class SearchView(TemplateView):
model = Post
template_name = "admin/search.html"
def get(self, request, *args, **kwargs):
q = request.GET.get('q', '')
self.results = Post.objects.filter(text__icontains=q, desc__icontains = q, title__icontains = q)
return super().get(request, *args, **kwargs)
Urls.py:
path('dashboard/listpost/search/', SearchView.as_view(), name="search")
ListPost.html:
{% extends "admin/layout.html" %}
{% block title %}
<title>Post List</title>
{% endblock title %}
{% block content %}
<form action="{% url 'search' %}" method="GET">
<input type="text" placeholder="Cerca" name="search"> <button>Cerca</button>
</form>
<div class="postlist">
<div class="cards"> <!-- Card Container -->
{% for post in object_list %}
<div class="card"> <!-- Single Card -->
{% if post.image %}
<img src="{{post.image.url}}" alt="">
{% endif %}
<h3>{{ post.title }}</h3>
<p>
{{ post.category }}
{{ post.author }}
<data class="data"> {{ post.date|date:'d-m-Y' }} </data>
</p>
<p class="desc-list">{{ post.desc|truncatewords:10 }}</p>
edit
delate
</div>
{% endfor %}
</div>
</div>
{% endblock content %}
Search.html
{% extends "admin/layout.html" %}
{% block title %}
<title>Search</title>
{% endblock title %}
{% block content %}
{% if query %}
{{Query}}
{% else %}
<p>Nope</p>
{% endif %}
{% endblock content %}
Your are trying to display the variable query, Query (two different variables since the template language is case sensitive).
Your do not pass any of those two variables in the template context.
I don't see any query nor Query variable in your view.
It seems that your want to show the results variable, so I will assume this.
Your need to send the results from your queryset in the template results.
The get_context_data method ContextMixin (one of the TemplateView derived classes) is useful for this.
class SearchView(TemplateView):
model = Post
template_name = "admin/search.html"
def get(self, request, *args, **kwargs):
q = request.GET.get('q', '')
self.results = Post.objects.filter(text__icontains=q, desc__icontains = q, title__icontains = q)
return super().get(request, *args, **kwargs)
def get_context_data(self, **kwargs):
"""Add context to the template"""
return super().get_context_data(results=results, **kwargs)
And in your template:
{% extends "admin/layout.html" %}
{% block title %}
<title>Search</title>
{% endblock title %}
{% block content %}
{% if results.exists %}
{% for result in results %}
{{ result }}
{% endfor %}
{% else %}
<p>Nope</p>
{% endif %}
{% endblock content %}

I have trouble finding the site

I do a search for articles on the site. Filtering should be by article title.
Data from the search should be displayed in the template/ I tried to filter the data using order_by and filter
views.py
def post_search(request):
form = SearchForm()
if 'query' in request.GET:
form = SearchForm(request.GET)
search = request.GET['username']
if form.is_valid():
cd = form.cleaned_data
results = SearchQuerySet().models(Articles).filter(content=cd['query']).load_all()
total_results = results.count()
return render(request,
'news/posts.html',
{'form': form,
'search': search,
'cd': cd,
'results': results,
'total_results': total_results})
posts.html
{% if "query" in request.GET %}
<h1>Posts containing "{{ cd.query }}"</h1>
<h3>Found {{ total_results }} result{{ total_results|pluralize }}</h3>
{% for result in results %}
{% with post=result.object %}
<h4>{{ post.title }}</h4>
{{ post.body|truncatewords:5 }}
{% endwith %}
{% empty %}
<p>There are no results for your query.</p>
{% endfor %}
<p>Search again</p>
{% else %}
<h1>Search for posts</h1>
<form action="{% url 'post_search' %}" method="get">
<h3>Search</h3><input style=" border: 3px solid #4242A3; border-radius: 15px ; " type="text" name="search" value=" searchк "> <br>
<input type="submit" value="Search">
</form>
{% endif %}
urls.py
path('search/', views.post_search, name='post_search'),
models.py
class Articles(models.Model):
title = models.CharField(max_length= 200)
post = models.TextField()
date = models.DateTimeField()
img = models.ImageField(upload_to='', default="default_value")
tags = TaggableManager()
article_like = models.IntegerField(default='0')
article_dislike = models.IntegerField(default='0')
view = models.IntegerField(default='0')
def __str__(self):
return self.title
If you are trying to search posts by the title of the articles then you can change your view like this:
def post_search(request):
query = request.GET.get('search')
if query:
results = Article.objects.filter(title__icontains=query).order_by('-date')
total_results = results.count()
return render(request,
'news/posts.html',
{
'results': results,
'query':query,
'total_results': total_results})
else:
messages.info(request,'no results found for {}',format(query))
And in your template you can do like this:
<h1>Posts containing "{{ query }}"</h1>
<h3>Found {{ total_results }} result{{ total_results|pluralize }}</h3>
{% for result in results %}
{% with post=result.object %}
<h4>{{ post.title }}</h4>
{{ post.body|truncatewords:5 }}
{% endwith %}
{% empty %}
<p>There are no results for your {{query}}.</p>
{% endfor %}
<p>Search again</p>
{% else %}

Django Template - neat 1-1 translation of values (dictionary lookup)

I've an object containing an attribute defined by a series of choices - here's it's class definition:
class StashURLJobRequest(models.Model):
STATUS_CHOICES = ((0,"Requested"),(1,"Done"),(2,"Failed"))
url = models.URLField()
created = models.DateTimeField(auto_now_add = True, auto_now=False)
processed = models.DateTimeField(auto_now_add = False, auto_now = True)
status = models.IntegerField(choices=(STATUS_CHOICES))
requestBy = models.CharField(max_length=32)
def __unicode__(self):
return smart_unicode(self.url + str(self.created))
def status_display(self):
status_dict = dict(self.STATUS_CHOICES)
return status_dict[self.status]
I get a list of these and pass through into a template, intending to render each one as an individual row, again, here's the template code:
{% for job_instance in jobs %}
<div class="width100pc">
<div class="width10pc"> <img src="{% static 'img/empty.png' %}" /> </div>
<div class="width80pc">
<div class="width70pc textleft sans textsmall "> {{ job_instance.url }} </div>
<div class="width15pc textcentre sans texttiny "> {{ job_instance.processed }} </div>
<div class="width5pc textcentre sans texttiny {% ifequal job_instance.status_display 'Done' %} status_green {% endifequal %}
{% ifequal job_instance.status_display 'Requested' %} status_amber {% endifequal %}
{% ifequal job_instance.status_display 'Failed' %} status_red {% endifequal %}"> {{ job_instance.status_display }} </div>
<div class="width10pc textcentre sans texttiny"> {{ job_instance.requestBy }} </div>
</div>
<div class="width10pc"> <img src="{% static 'img/empty.png' %}" /> </div>
</div>
{% endfor %}
In particular, note the section:
{% ifequal job_instance.status_display 'Done' %} status_green {% endifequal %}
{% ifequal job_instance.status_display 'Requested' %} status_amber {% endifequal %}
{% ifequal job_instance.status_display 'Failed' %} status_red {% endifequal %}
Each of {status_green, status_amber and status_red} refer to a different css class, and allows me to render the status in an appropriate colour.
This seems a little unwieldy, and I don't want to code the css-class into the model, or the view (preferring to leave format and display to the template/html definitions) - so the question is, is there a way to do this that's more "pythonic" - ideally, I'd like to use something like:
{{ class_dict = {'Done' : 'status_green', 'Requested' : 'status_amber', 'Failed' : 'status_red' } }}
< ... some code ... >
{{ class_dict[job_instance.status_display] }}
(dodgy curly-braces aside!)
Add a helper function to the object, so that you don't need any logic in the template?
Add to StashURLJobRequest
def status_display_colour(self):
return {
"Done":"status_green",
"Requested":"status_amber",
"Failed":"status_red"
}[ self.status_display() ]
And the template becomes <div class="width5pc textcentre sans texttiny {{ job_instance.status_display_colour }} ...
Another way would be class="... my-class-{{job_instance.status_display}}" with my-class-Done, my-class-Requested, my-class-Failed appropriately defined in your css. It's inferior because it depends implicitly on status_display remaining a single word with no spaces or other special characters.

django-nvd3 load_chart tag evaluates to False in output HTML and no chart is displayed

I'm trying to implement a pieChart using django-nvd3. However, the output html of {% load_chart charttype chartdata chartcontainer extra %} evaluates to False. Resultantly (most likely) the chart fails to appear. Below is the view.py, django template and html output.
View.py
def results(request, nlm_id, time):
journal = Journal.objects.get(nlm_id = nlm_id)
stats = return_week(nlm_id, time, PLATFORMS)
chartdata = {'x': PLATFORMS, 'y': stats}
charttype = "pieChart"
chartcontainer = 'piechart_container'
data = {
'charttype': charttype,
'chartdata': chartdata,
'chartcontainer': chartcontainer,
'extra': {
'x_is_date': False,
'x_axis_format': '',
'tag_script_js': True,
'jquery_on_ready': True,
}
}
return render(request, 'journals/results.html', {'journal': journal,
'stats': stats, 'time': time, 'data': data})
Template
{% extends "base.html" %}
{% load staticfiles %}
{% load nvd3_tags %}
<head>
{% block style %}
{{ block.super }}
{% include_chart_jscss %}
{% load_chart charttype chartdata chartcontainer extra %}
{% endblock %}
</head>
<body>
{% block content %}
{% include_container chartcontainer 400 600 %}
{% endblock %}
</body>
Output HTML
<html>
<head>
...
<script>False</script>
</head>
<body>
<div id=""><svg style="width:600px;height:400px;"></svg></div>
</body>
</html>
A solution could be to pass the variables charttype, chartdata, chartcontainer, and extra directly like this:
context = {
'charttype': charttype,
'chartdata': chartdata,
'chartcontainer': chartcontainer,
'extra': {
'x_is_date': False,
'x_axis_format': '',
'tag_script_js': True,
'jquery_on_ready': False,
},
'journal': journal,
'stats': stats,
'time': time,
}
return render(request, 'journals/results.html', context)
I faced similar problem and I fixed it when I changed {% load_chart charttype chartdata chartcontainer extra %}
to {% load_chart data.charttype data.chartdata data.chartcontainer data.extra %}
and similarly {% include_container chartcontainer 400 600 %} to {% include_container data.chartcontainer 400 600 %}
You can wrap your load_chart in an if statement which checks that there is chartdata, eg:
{% if chartdata %}
{% load_chart charttype chartdata chartcontainer extra %}
{% endif %}

Categories