How to get rtf displayed in Django app? - django

I'm creating an blog app in Django. In a form I'm using ckeditor in order to get the rich text format from the user. Now the data is saved in the database in the RTF with all tags. Now I want to retrieve data from database and display it to the user but unable to do so. In output data with tags is displayed.
my code goes like this.
class blog(models.Model):
title = models.CharField(max_length = 200, unique = True)
slug = models.SlugField(max_length = 200, unique = True)
body = RichTextField()
uid = models.AutoField(primary_key = True)
posted_on = models.DateField(auto_now_add= True, db_index = True)
blogger = models.ForeignKey(blogger)
def __str__(self):
return self.title
form.html:- form for entry
<form method = 'POST' action = "{% url 'blog.views.addblog' %}">
{% csrf_token %}
<div class="form-group">
{}
{{form|crispy}}
<center>
<input type="submit" class="btn btn-success" value = "Post"></center>
</form>.
This is how I'm trying to display data on another HTML page. Blog is context passed containing blog details like body and title:
<h1>{{blog.title }}</h1>
<p> {{blog.body|linebreaks}}</p>
how to get data back in rich text format?

well a lot of research. Answer is so easy i was wondering why i couldn't figure it out.
I just had to use safe keyword in following manner.
<h1>{{blog.title }}</h1>
<p> {{blog.body|safe}}</p>

Related

Post of data from ListBox is not being rendered to the database

I have an app that takes as one of the form fields a multiple listbox. The data is defined on the html page as "temp_groups", then in the view.py the form.cleaned_data['actual field'] is set to the extracted temp field. The data extracted appears correct (2,3) and looking at the same field after the form.save() is executed looks correct. But the data is not rendered to the database that way. It is using the value set on the actual "hidden" field on the html page. Here is the code
Tried using the actual field name (group_members) but the result is only the last value selected from the list is actually posted.
Also tried setting up a widget on the forms.py file where the data used in supplying comes from the query of the User object (auth_user). But this had no impact.
url.py
urlpatterns = [..
path('newgroups/', views.newgroups, name='newgroups'),
forms.py
class QueryGroupsForm(forms.ModelForm):
class Meta:
model = QueryGroups
fields = ['group_name',
'group_desc',
'group_members',
]
models.py
class QueryGroups(models.Model):
group_name = models.CharField(max_length=40, null=True, blank=True)
group_desc = models.CharField(max_length=100, null=True, blank=True)
group_members = models.CharField(max_length=100, null=True, blank=True)
querygroups.html
<div class="col-3">
<div class="form-group">
<label for="temp_members" class="" style="font-weight: bold;">Group Members<label>
<select id="temp_members" name="temp_members" class="form-control" multiple="multiple">
{% for nextUser in users %}
<option value="{{nextUser.id}}">{{nextUser.username}}</option>
{% endfor %}
</select>
<input type="hidden" name="group_members" id="group_members" value="TBD">
</div>
</div>
views.py
def newgroups(request):
if request.method == "POST":
group_form = QueryGroupsForm(request.POST)
user_list = request.POST.getlist('temp_members')
users_of_group = ""
for next_user in user_list:
users_of_groups += next_user + ","
list_len = len(users_of_groups)
users_of_group = users_of_group[:list_len - 1]
if group_form.is_valid():
group_form.cleaned_data['group_members'] = str(user_of_group)
group_form.save()
post_list = group_form.cleaned_data['group_members']
return HttpResponse("user_of_group: " + users_of_group + " post_list: " + str(post_list))
What is presented on the HttpResponse is "users_of_group: 2,3 post_list: 2,3". However, what is in the group_members field in the database is the value "TBD" which is set as the hidden field in the html file.

Uploading 2 single files on a form using separate inputs: Django

I'm trying to build an application that asks users to upload 2 different pdf files, each from a separate input button/area. I'm new to Django and through reading the documentation a bunch of times I've gotten a few things to work.
Using <form method="post" enctype="multipart/form-data"> I was able to get 2 fields for input which look something like this: App Screenshot of 2 input areas.
However, when I click the select button in either case and select the file and click 'Upload', The same 2 files show up in both input areas. I've experimented with this alot and can't seem to find any resources that attempt to solve my problems.
Quick note: I know there are ways to upload multiple files in a single input area, but I don't want to do that. I want to specifically have 2 different input areas as a design decision.
I'm not sure if this even close to the right approach or if there are better tools for handling this type of situation. Below are chunks of the code I've written. If anyone could give me advice on how to better approach this problem or tell me how to fix my code it would be much appreciated.
Thanks!
forms.py
class FilePDFForm(forms.ModelForm):
class Meta:
model = FilePDF
fields = ('identifier', 'pdf', 'pdf2' )
models.py
class FilePDF(models.Model):
identifier = models.CharField(max_length=50, blank = True)
pub_date = models.DateTimeField(auto_now_add=True)
pdf = models.FileField(upload_to='documents/')
pdf2 = models.FileField(upload_to='documents/')
def __str__(self):
return self.pdf.name + ',' + self.pdf2.name
views.py
def index(request):
if request.method == 'POST' and request.FILES['myfile'] and request.FILES['myfile2']:
genfile = request.FILES['myfile']
genfile2 = request.FILES['myfile2']
fs = FileSystemStorage()
filename = fs.save(genfile.name, genfile)
filename2 = fs.save(genfile2.name, genfile2)
uploaded_file_url = fs.url(filename)
uploaded_file2_url = fs.url(filename2)
file1_uploaded = True
return render(request, '...index.html', {
'uploaded_file_url': uploaded_file_url,
'uploaded_file2_url': uploaded_file2_url,
'file1_name': filename,
'file2_name': filename2
})
return render(request, '...index.html')
index.html
<div class="col-xs-3">
<div class="form-group">
<label class="control-label">Please select the first PDF file from your
computer.</label> <input type="file" class="filestyle" name="myfile"
data-buttontext=" Select" data-buttonname="btn btn-primary" /><br />
<label class="control-label">Please select the second PDF file from your
computer.</label> <input type="file" class="filestyle" name="myfile2"
data-buttontext=" Select" data-buttonname="btn btn-primary" /> <button type=
"submit" class="btn btn-primary">Upload</button>
</div>
</div>
Change your view like this form,
def index(request):
if request.method == 'POST':
f = FilePDFForm(request.POST, request.FILES)
if f.is_valid():
new_object = f.save()
# do remaining thing here
-----------------
return render(request, '...index.html')
for more refer this https://docs.djangoproject.com/en/1.11/topics/forms/modelforms/#modelform

TypeError: render_option() argument after * must be a sequence, not int

I am willing to use Django for a school project but I'm encountering several issues.
The one I need help for is described in the title. Basically, I have a todo application in which I could add tasks. Now that I added a form in a my view to let the user add a task, I can't access the tasks in the Django admin.
I can still delete them with the admin but each time I try to add or to edit a task through the admin it throws me this error :
TypeError at /admin/todo/task/12/`
render_option() argument after * must be a sequence, not int
But, the form I added for the user works well.
My guess is that the 12 we can see the url is making the error but I don't know why. I point out that I'm still kinda new to Django, I didn't find any similar problem (found this but it didn't help me) so I thought it could be a good idea to ask here :). Here are my files :
todo/models.py
PRIORITY_TYPES = (
(1, 'Normal'),
(2, 'High'),
)
class Task(models.Model):
application = models.CharField(max_length=120, default='esportbets')
title = models.CharField(max_length=120)
author = models.CharField(max_length=60, blank=True, null=True)
created = models.DateTimeField(auto_now_add=True)
completed = models.DateTimeField(blank=True, null=True)
priority = models.IntegerField(choices=[PRIORITY_TYPES], default=1)
done = models.BooleanField(default=False)
def __unicode__(self):
return self.title
todo/forms.py
class AddTaskForm(forms.Form):
application = forms.CharField(max_length=120, initial='esportbets', help_text='the application it is about')
title = forms.CharField(max_length=120, help_text='the task to do')
priority = forms.ChoiceField(choices=PRIORITY_TYPES, initial=1)
todo/views.py
def index(request):
if request.method == 'POST':
form = AddTaskForm(request.POST)
if form.is_valid():
new_task = Task.objects.create(application=form.cleaned_data['application'],
title=form.cleaned_data['title'],
priority=form.cleaned_data['priority'])
request.POST = None
redirect('/todo/', RequestContext(request))
else:
form = AddTaskForm()
tasks = Task.objects.all().order_by('-created')
tasks_high = tasks.filter(priority=2)
tasks_normal = tasks.filter(priority=1)
template_datas = {'form':form, 'tasks_high':tasks_high, 'tasks_normal':tasks_normal, 'user':request.user}
return render_to_response('todo/base.html', template_datas, RequestContext(request))
todo/base.html
{% if user.is_authenticated %}
<hr /><h3>ADD A TASK</h3><br />
<form method="post" action=".">
{% csrf_token %}
{{ form.as_p }}
<br />
<input type="submit" value="add" />
<input type="reset" value="reset" />
</form>
{% endif %}
todo/models.py: remove the [] around PRIORITY_TYPES.
todo/forms.py: replace the forms.ChoiceField(...) by forms.TypedChoiceField(choices=PRIORITY_TYPES, initial=1, coerce=int)
Since you are essentially copying data 1:1 from the form to a model, I'd recommend using django.forms.ModelForm.
If you want to minimize your code further you could use the generic CreateView. I recently wrote an answer to "Best practices on saving in a view, based on example code" which includes some example code.

Merging querysets from different models

I have 2 models in one app and 1 view. I'm currently pulling information from 1 model perfectly fine. However i wish to pull in another model from the same app and output them both to the same page.
The idea of the page is it being a a news hub so it's pulling through different types of news posts (from one model) and a different type of post which is from the other model.
I'm fairly new to Django so go easy! :) Anyway here is the code:
//VIEWS
def news_home(request):
page_context = details(request, path="news-hub", only_context=True)
recent_posts = NewsPost.objects.filter(live=True, case_study=False).order_by("-posted")[:5]
recent_posts_pages = Paginator(recent_posts, 100)
current_page = request.GET.get("page", 1)
this_page = recent_posts_pages.page(current_page)
notes = BriefingNote.objects.filter(live=True).order_by("-posted")
news_categories = NewsCategory.objects.all()
news_context = {
"recent_posts": this_page.object_list,
"news_categories": news_categories,
"pages": recent_posts_pages,
"note": notes,
}
context = dict(page_context)
context.update(news_context)
return render_to_response('news_hub_REDESIGN.html', context, context_instance=RequestContext(request))
//model 1
class BriefingNote(models.Model):
title = models.CharField(max_length=300)
thumbnail = models.ImageField(upload_to='images/briefing_notes', blank=True)
file = models.FileField(upload_to='files/briefing_notes')
live = models.BooleanField(help_text="The post will only show on the frontend if the 'live' box is checked")
categories = models.ManyToManyField("NewsCategory")
# Dates
posted = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
def __unicode__(self):
return u"%s" % self.title
// model 2
class NewsPost(models.Model):
title = models.CharField(max_length=400)
slug = models.SlugField(help_text="This will form the URL of the post")
summary = models.TextField(help_text="To be used on the listings pages. Any formatting here will be ignored on the listings page.")
post = models.TextField(blank=True)
#TO BE REMOVED????
thumbnail = models.ImageField(help_text="To be displayed on listings pages", upload_to="images/news", blank=True)
remove_thumbnail = models.BooleanField()
I'm outputting the content on the front end like so:
{% for post in recent_posts %}
<div class='news_first'>
<img class="news_thumb" src="/media/{% if post.article_type %}{{post.article_type.image}}{% endif %}{% if post.news_type %}{{post.news_type.image}}{% endif%}" alt="">
<h3><a href='{{post.get_absolute_url}}'>{% if post.article_type.title %}{{post.title}}{% endif %} <span>{{post.posted|date:"d/m/y"}}</span></a></h3>
<p class='news_summary'>
{% if post.thumbnail %}<a href='{{post.get_absolute_url}}'><img src='{% thumbnail post.thumbnail 120x100 crop upscale %}' alt='{{post.title}}' class='news_thumbnail'/></a>{% endif %}{{post.summary|striptags}} <a href='{{post.get_absolute_url}}'>Read full story ยป</a>
</p>
<div class='clearboth'></div>
</div>
{% endfor %}
I was thinking perhaps i could output them both within the same forloop however they need to ordered by -posted. So i though this could mess things up.
If you need anymore info please let me know.
Thanks in advance.
I've now solved the problem.
news_hub = list(chain(notes, recent_posts))
news_hub = sorted(
chain(notes, recent_posts),
key = attrgetter('posted'), reverse=True)[:10]

Django form not saving default image name

I've got a form which includes the option to upload an image. In my model, I've defined a default image name to use when no image is selected for upload. When selecting a file, the form uploads the file to my media directory and properly places the filename in the db field (working as it should). When not selecting a file, that field is left blank in the db. When adding an item to that same db table using Django Admin, the default filename is correctly placed in the db field when no image is selected (and works properly when an image is selected). It's only when using the form and not selecting an image does it not work properly. I've look around for a while but have yet to come up with anything that could help. Any ideas? Any help is much appreciated.
models.py
class Beer(models.Model):
beername = models.CharField(max_length=150)
brewer = models.ForeignKey(Brewery)
style = models.ForeignKey(BeerStyle)
abv = models.DecimalField(max_digits=4, decimal_places=2)
beerdescription = models.TextField()
picture = models.ImageField(upload_to='site_media/pictures/',
default='pictures/no_beer_picture.jpg')
def __unicode__(self):
return self.beername
forms.py
class BeerAddForm(forms.Form):
beername = forms.CharField(
label=u'Name',
widget=forms.TextInput(attrs={'size': 75})
)
style = forms.ModelChoiceField(
BeerStyle.objects.all(),
label=u'Style',
widget=forms.Select()
)
abv = forms.DecimalField(
label=u'ABV',
widget=forms.TextInput(attrs={'size': 8})
)
beerdescription = forms.CharField(
label=u'Description',
widget=forms.Textarea
)
picture = forms.ImageField(
required=False,
label=u'Picture',
widget=forms.FileInput,
initial='pictures/no_beer_picture.jpg'
)
views.py
def beeradd(request, brewery_id):
brewery = get_object_or_404(Brewery, id=brewery_id)
if request.method == 'POST':
form = BeerAddForm(request.POST, request.FILES)
if form.is_valid():
# Create or get beer
beer = Beer.objects.create(
beername = form.cleaned_data['beername'],
brewer = brewery,
style = form.cleaned_data['style'],
abv = form.cleaned_data['abv'],
beerdescription = form.cleaned_data['beerdescription'],
picture = form.cleaned_data['picture']
)
return HttpResponseRedirect('/beers/')
else:
form = BeerAddForm()
variables = RequestContext(request, {
'form': form
})
return render_to_response('beer_add.html', variables)
beer_add.html (the form in question)
{% extends "base.html" %}
{% block title %}Add a Beer{% endblock %}
{% block head %}Add a Beer{% endblock %}
{% block content %}
<form enctype="multipart/form-data" method="post" action=".">
{{ form.as_p }}
<input type="submit" value="save" />
</form>
{% endblock %}
I would set the default in the view code, after the user submitted the form. So take the initial argument for picture out of the form definition and do something like this in your view:
def beeradd(request, brewery_id):
brewery = get_object_or_404(Brewery, id=brewery_id)
if request.method == 'POST':
form = BeerAddForm(request.POST, request.FILES)
if form.is_valid():
# Create or get beer
pic = form.cleaned_data['picture']
if not pic:
pic = 'pictures/no_beer_picture.jpg'
beer = Beer.objects.create(
beername = form.cleaned_data['beername'],
brewer = brewery,
style = form.cleaned_data['style'],
abv = form.cleaned_data['abv'],
beerdescription = form.cleaned_data['beerdescription'],
picture = pic
)
...
I think the problem that you are seeing is that the initial may populate the file field with that value, but when the form gets submitted the value 'pictures/no_beer_picture.jpg' is not a valid file on the user's computer so no file is sent with the form. You can verify what is getting sent by printing out form.cleaned_data['picture'] before trying to save the model.
You may want to check to see if you can just assign a string value to the picture attribute on Beer or if you actually need to assign a file.