How to create a form for blog posts that accepts image uploads

180 views
Skip to first unread message

Ryan M

unread,
Sep 15, 2017, 8:59:50 AM9/15/17
to Mezzanine Users

I have been migrating my existing blog to Mezzanine.  It has been a great experience so far.  Mezzanine has been able to accommodate all of the features on my "wish list" so far with the exception of the few "hiccups" below.  Fortunately, I am positive that these outstanding problems can be overcome, it's just a matter of me learning more about Mezzanine and Django.  I'd appreciate your help!

1)
I want to have a "create new post" button that links to a "form" for creating a blog post.  The form will ask the user for a blog post title, content, and an optional featured image.  The featured image will prompt an upload that must work on smartphones.
So far I am able to get all of this to work except for the image upload part.  I've tried a few different ways of setting it up - in some cases the upload image button doesn't do anything, in other cases it launches a new window with the admin content management gui, and with some tweaking i can get the upload button to work but the site bombs when the "request.FILES" object is passed.  The admin content management gui isn't really ideal for my blog, i'd prefer for it to go directly to an upload prompt.

2)
I added two new columns to my blog_blogPost table in the database, but - unsurprisingly - these columns are not accessible when I refer to them in the blog detail or blog list pages.  I suspect they need to be added to the model, not sure how to do that.


I am thinking I need to ditch the standard "blog" app and instead make my own blog app that somehow extends the default blog app.  I am not 100% sure about how to do this, but its on my short list of possible options for resolving the issues above.

I am fairly strong with python and web design, but I'm still learning django.  If you steer me in the right direction, I think I can figure it out.

Thanks for the help!
Ryan

Melvyn Sopacua

unread,
Sep 15, 2017, 11:38:01 AM9/15/17
to mezzani...@googlegroups.com
If you're failry strong in python, but not Django and are working with
Mezzanine, then you do need to do some digging into Django. And here's
the main pointers:

- Models are classes that represent the database structure. They can
be extended, they can be marked abstract, but the primary thing to
remember is that model **fields** cannot be overwritten. Model fields
being attributes of the class that are extending
django.db.models.Field. The represent table fields and therefore are
actively prevented from being extended.
- Database tables are migrated using Django migrations. In general
it's not necessary to know the database structure let alone even touch
it. This is only needed for specialized cases, optimizations and
legacy databases.
- Django form fields have a widget kwarg in their __init__, which can
be used to override the widget at runtime. Additionally, the Django
Form class has a metaclass attribute "widgets" which is a dictionary
mapping field names to widgets.

These points are all accessible from
https://docs.djangoproject.com/en/1.11/ and quite a bit of it covered
in the tutorial.

Mezzanine:
- A blog image is already available, when the following is activated
in settings:

# Setting to turn on featured images for blog posts. Defaults to False.
#
# BLOG_USE_FEATURED_IMAGE = True
- The default widget for a Mezzanine FileField is from
filebrowser_safe. It should be possible to set this to
django.forms.ClearableFileInput, though I've not tried it.

Hope this helps.
> --
> You received this message because you are subscribed to the Google Groups
> "Mezzanine Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to mezzanine-use...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.



--
Melvyn Sopacua

Ryan M

unread,
Sep 15, 2017, 1:17:15 PM9/15/17
to Mezzanine Users
Melvyn,

This does help.  Your input is very much appreciated!  Since this is a "night-time" project for me, I will need to review my code within the context of the "widget" info you provided later tonight.  I especially look forward into reading about "filebrowser_safe", as that might be the key to resolving my first issue.

The main thing I wanted to resolve from my post is still a little unclear to me though:
  • To meet my two remaining "objectives", do I need to make my own blogPost model that extends the mezzanine built-in, or is it achievable with the built-in?
I feel like knowing the answer to this will steer me in the direction that I need to research.

Thanks again,
Ryan

Melvyn Sopacua

unread,
Sep 15, 2017, 11:22:18 PM9/15/17
to mezzani...@googlegroups.com
I don't know what the two columns are for. Generally if you need to do
more with a model, you should extend the model. But if you only need
more fields, there's also EXTRA_MODEL_FIELDS in the settings that does
all the work for you. It is explained in the comments of the settings
file.

As far as the image upload blowing up on mobile, I think that's a red
herring. The default settings for upload size are conservative, so
perhaps what you're uploading is too big (generally, anything coming
from a decent mobile phone camera will be).

This should point you in the right direction:
https://docs.djangoproject.com/en/1.11/ref/settings/#std:setting-FILE_UPLOAD_MAX_MEMORY_SIZE

(and read the linked refs)

Ryan M

unread,
Sep 16, 2017, 2:16:44 AM9/16/17
to Mezzanine Users
I worked my way through the first of these two issues.  Your input was useful.  And after a bit of reading, I am confident that the EXTRA_MODEL_FIELDS will be the solution to my second issue.

I am still a little peeved about how "filebrowser_safe" behaves.  This is not related to any filesize issues or anything like that.  It's just that it makes a pop-up to upload an image.  Pop-ups are unpleasant on phones, and I have a feeling this will throw my non-tech savvy users for a loop.  Any way to circumvent this?

Either way, I appreciate the help you've given me thus far!
Ryan

Ryan M

unread,
Sep 16, 2017, 9:47:44 AM9/16/17
to Mezzanine Users
After some poking around - I found that replacing PACKAGE_NAME_FILEBROWSER = "filebrowser_safe" with PACKAGE_NAME_FILEBROWSER = "filebrowser" circumvents the whole pop-up issue.  I suspect I am also circumventing some piece of security aswell (hence the "safe"), but it's mission accomplished for now.

Ryne Everett

unread,
Sep 16, 2017, 11:48:21 AM9/16/17
to mezzani...@googlegroups.com
While several security issues have been recognized and patched in
filebrowser_safe more readily than in filebrowser, the "safe" aspect is
a reference to package stability and not security. However, I would be
very surprised if use of Filebrowser with Mezzanine does not have
numerous bugs and broken features. Filebrowser_safe has
Mezzanine-specific code in it that Filebrowser does not.

Ryan M

unread,
Sep 16, 2017, 9:39:51 PM9/16/17
to Mezzanine Users
Understood.  I will keep filebrowser on my radar for potential revisions to my blog.

Melvyn Sopacua

unread,
Sep 17, 2017, 8:56:14 AM9/17/17
to mezzani...@googlegroups.com
The popup is used in the admin to allow selection of previously
uploaded files. This allows distributed uploading (graphics department
uploading and authors picking the right one for the story). If that's
not what you need as you will always want to use a new image, then
simply override the widget and either make your own or use
`django.forms.ClearableFileInput`, easiest way through:
https://docs.djangoproject.com/en/1.11/ref/contrib/admin/#django.contrib.admin.ModelAdmin.formfield_overrides

Larry

unread,
May 21, 2019, 11:06:17 AM5/21/19
to Mezzanine Users
Ryan,

Is it possible to share your solution to #1? How to create a new post from the user side without going through admin.
Thanks,
Larry

Jhon Edison Bueno Martínez

unread,
Apr 9, 2020, 11:47:52 PM4/9/20
to Mezzanine Users
This really helps! It was so simple. Thanks.
Reply all
Reply to author
Forward
0 new messages