Dynamically create and save image with Django and PIL/Django-Photologue - django

I want to generate a page of html with dynamic content and then save the result as an image as well as display the page to the user. So, user signs up to attend conference and gives their name and org. That data is combined with html/css elements to show what their id badge for the conference will look like (their name and org on top of our conference logo background) for preview. Upon approval, the page is saved on the server to an image format (PNG, PDF or JPG) to be printed onto a physical badge by an admin later. I am using Django and django-photologue powered by PIL.
The view might look like this
# app/views.py
def badgepreview(request, attendee_id):
u = User.objects.get(id=attendee_id)
name = u.name
org = u.org
return render_to_response('app/badgepreview.html',
{'name':name,'org':org,},
context_instance = RequestContext(request),
)
The template could look like this
{# templates/app/badgepreview.html #}
{% extends "base.html" %}
{% block page_body %}
<div style='background:url(/site_media/img/logo_bg.png) no-repeat;'>
<h4>{{ name }}</h4>
<h4>{{ org }}</h4>
</div>
{% endblock %}
simple, but how do I save the result? Or is there a better way to get this done?

The only thing I can think is to do it in two passes:
a) Use http://www.xhtml2pdf.com/ to convert the HTML into a PDF.
b) Use something like http://www.swftools.org/gfx_tutorial.html to convert the PDF into an image.
I can't imagine that doing this would be fast...
You might be better off just converting and allowing them to download a PDF (i.e. use just step a) above) or trying to generate the badge directly without the HTML intermediate step.

Related

How to process django url tags in context variables

I'm creating a django-based website where page content is stored in a model textfield with a detail view of the model displaying it. How can I put {% url %} tags in the content to link to other pages without hard coding links?
Putting the tag into the textfield will just print the tag as plain text. (or if inside an href create a broken link)
Other options are
parsing the content manually inside the view and replacing the tags with the correct url
using some django supplied string parser to create the links before sending to the template
maybe there is a way to do it in the template with a filter or tag around the variable.
I could probably do the manual way but I am hoping there is a django way that I am missing.
class Page(models.Model):
content = models.TextField(blank=True)
class PageView(DetailView):
model=Page
context_object_name='page'
{% extends "base.html" %}
{% block content %}
{{ page.content|safe }}
{% endblock %}
Edit for clarity:
Content in admin
What it renders
What it should render
Edit 2:
I was able to find a solution to the second option thanks to this answer on another question. Using that template_from_string function I rendered the page content as a template then replaced the content in the context with the rendered result.
class PageView(DetailView):
model=Page
context_object_name='page'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
# Add to context here
context['page'].content = template_from_string(context['page'].content).render(context)
return context
your url's will have a name as shown below-
path('page//',PageView.as_view, name="page-detail")
and in your Page Detail
hope this is what your asking for
Let see if I understood you well, do you want django to show you a url as such and not as plain text?
If you want to avoid django to show you the data as plain text, you can use the escape filter as follows: {{string | escape}}
Check this page for more details about django filters and tags

Customizing Wagtail Streamfield

Can anyone provide the code necessary to create the Wagtail Streamfield options that are previewed on the wagtail.io website front page?
https://media.wagtail.io/images/w1_5pmaP1U.original.width-1600.png
Specifically, I'm interested in Aligned Image, Wide Image, Bustout, Raw HTML, and Markdown.
This page describes how to freeform page content using StreamField (blocks).
https://docs.wagtail.io/en/latest/topics/streamfield.html
You can subclass any built-in block and provide your own template:
class WideImage(ImageChooserBlock):
class Meta:
label = 'Wide image'
icon = 'image'
template = 'website/blocks/wide_image.html'
The html is up to you:
{% load wagtailimages_tags %}
{% image self width-1024 as img %}
<img src="{{ img.url }}" class="image--wide">
Ofcourse the css is up to you too.
.image--wide { width: 100% }
What the exact markup and styling should be, depends on your current frontend markup and styling.
Aligned Image, Wide Image and Bustout can be achieved in the same way. Simple markup and little css.
Raw HTML is an existing block
https://docs.wagtail.io/en/latest/topics/streamfield.html#rawhtmlblock
You can store your markdown in a TextBlock.
https://docs.wagtail.io/en/latest/topics/streamfield.html#textblock
Converting markdown to html is a three line custom string filter:
#stringfilter
def md(value):
return markdown2.markdown(value)
Use it in your template:
{% load app_tags %}
{{ self|md }}

Django get data from two tables, related data only

Okay so I have a homepage that displays images. This is accessed from my images tables. It contains a column of the owner, in the form of a user id. I also have a table of users, who've submitted those images. How do I make it so that when displaying images, it uses the ID to get the username from the user table?
views.py:
def index(request):
context = {}
populateContext(request, context)
context.update(gallery=ImageDoc.objects.only('thumbfile').order_by('-id'))
return render(request, 'register/index.html', context)
So in the index.html page, I can iterate through 'gallery' to show the images. Like so:
{% for image in gallery %}
<a href="/logo/{{ image.slug }}">
<img src="{{ MEDIA_URL }}{{ image.largethumbfile }}">
{{ image.title }} by {{ image.username }} for {{ image.price }}
</a>
{% endfor %}
"image.username" obviously doesn't work. I know I need to access the users table with this:
get_users = User.objects.get()
And reformat grabbing the images data to this:
get_images = ImageDoc.objects.get()
But I don't know the next step to ensure the data matches. Any ideas? Thank you!
If the Images table has the Users table as a foreign key, then each Images object will have a user_id parameter. Therefore, if you have a value called given_user_id you can do something like:
Images.objects.get(user_id=given_user_id)
If you have a username instead of a user_id, you can do something like:
Images.objects.get(user=User.objects.get(username=username))
Unfortunately, you cannot perform queries inside of a template block. You'll need to do any querying before you pass in your context object to the render function.

How to display a couchdb image attachment in a Django template

I am using couchdb-python with Django. I am looking for a way to display an image (which is stored in the database as an attachment to a document) in a template. Oddly, I cannot find any example online of how to do this.
Currently, in the views.py I have something like this:
def displaypage(request,id):
docs = SERVER['docs']
try:
doc = docs[id]
except ResourceNotFound:
raise Http404
...
attachments = doc['_attachments']['someimage.jpg']
...
text_marked_down = markdown.markdown(doc['text'])
return render_to_response('couch_docs/display.html',{'row':doc,'attachments':attachments,'doctext':text_marked_down,...},context_instance=RequestContext(request))
Then, in the template display.html:
{% extends 'site_base.html' %}
{% block wrapper %}
{{ attachments }}
<div>{{ doctext|safe }}</div>
{{ endblock }}
I am seeing the text just fine, but for the image I only see the following:
{u'stub':True, u'length':27018,u'revpos':19,u'content_type': u'image/jpeg'}
So, clearly I am not passing the actual image, or not displaying it correctly anyway. Oddly, I cannot find an example online anywhere of how to actually do this. Can anyone point me to one, or provide it here?
You are using the template engine to render an HTML document. That document will be interpreted by the web browser just like any other HTML document.
Think about how an HTML page contains an image. The image is never inline within the HTML document itself. The HTML page contains a reference to instruct the browser to separately load the image and display it in place.
<img src="/path/to/image" />
So, likewise, you will need to:
create a separate view that will only return the binary data of the image. Set the mime type appropriately. See http://effbot.org/zone/django-pil.htm for some ideas how to return an image, but in your case set the contents of the response to be your image content.
add an <img ...> tag to your template that calls the new view you created.
once you drill down your db, you might want to consider building the url of each documents attachment as follows:
def function():
couch = couchdb.Server() #connect to server
db = couch['img'] #connect to database which contains docs with img attachments
doc_id = [] #create list of id's
http_docid = [] #create list to populate href for picture path
for i in db: #for each id in the db
doc_id.append(i) #add to the carid list
doc = db[i] #get the document id
for key in (doc['_attachments']): #for the key in the doc '_attacments' payload
print key #just to confirm
href_docid.append(('http://yourdbDomain/dbname/'+i+'/'+key)) #create a uri and append to a list
return href_docid
And below im using Jinja2's templating:
{% for img in function() %}
<img class="some-class" src="{{ img }}">
{% endfor %}
Hope this proves usefull!

Displaying page content using django-page-cms

I would like to display some content located in my models in some of my template pages.
I am using django-page cms
In the documentation views are not used to display content. Instead ready made template tags are used.
http://packages.python.org/django-page-cms/display-content.html
I do not understand a word of this. Please Bear with me I am new.
All I want to do is display some info located in my models inside a template this manner..
{% if latest_news_list %}
{% for news in latest_news_list %}
<li><h3>{{ news.title }}</h3></li>
<li><p>{{ news.body }}</p></li>
{% endfor %}
Since views are not used I cannot use if latest_news_list.
I need to somehow get my models to display in the templates using django-page cms and NOT regular views. The documentation states to use some kind of template tag for this.
Could somebody please explain to me how to do this.
And a clear concise explanation of the following ready-made template tags would also be appreciated...
* get_content
* show_content
* get_page
* show_absolute_url
taken from.http://packages.python.org/django-page-cms/display-content.html
I need to display info contained using the following models in the manner I have highlighted above. Thank you very much for your help. my models are as follows.
class Body(models.Model):
type = models.ForeignKey(Content)
title = models.CharField(max_length=100)
published = models.DateTimeField(default=datetime.now)
body = tinymce_models.HTMLField("Main content")
As I have stated I am very new to this please make explanations as simple as possible.
The template tags you mentioned are supposed to display content coming from the cms. If you want to include data coming from your app, you should see this sectionlink text.
def extra_context():
from myapp.models import Body
items = Body.object.all()
return {'items': items}
PAGE_EXTRA_CONTEXT = extra_context
{% if items %}
<ul>
{% for item in items %}
<li>{{ item.title }} </li>
{% endfor %}
<ul>
{% endif %}
Or, if you want to use your app's view, see this.