Multi-page django form - slider or FormWizard? - django

I have a long form that I want to break into multiple pages.
I am evaluating between two options for presentation:
Present the form on multiple pages using the FormWizard
Present the form on a slider like CSS3 slider.
The slider is actually just one page long using CSS3 to give impression of slides. It floats all of the content areas next to each other, hides the overflow, sets page width to say 500% if we have 5 slides, and moves the left-margin -100% to show the next slide. So it is all one page but seems like the form is being shown on sliding pages.
To me the advantage of slider approach is that there is only one form and the user submits the form only once at the end of slides and thus can go back and forth to make changes.(This is will be a common case).
Versus having mini-Forms for FormWizard and submitting them after each page. To me, FormWizards seems complicated especially if the user wants to change any of previous page responses. I also need FileField on my form pages and it seems like FormWizard accepts FileField only on the last page.
However, I have not seen many folks use this sliding forms (CSS3 or JScript one) approach. Hence, as a newbie, I am wondering if there are some obvious pitfalls of doing this?

I can only write about FormWizard as I have used it before. According to 'Handling Files' section of Django documentation which can be found in
https://docs.djangoproject.com/en/dev/ref/contrib/formtools/form-wizard/
a FileField can be used in any step of your FormWizard implementation. What I found really helpful by using FormWizard from Django, is that it provides you all the standard functionality of Forms. That means that you can easily create and manipulate forms, validate fields in each step, etc. I am not aware of how CSS3 slider accomplishes validation, but I guess that validation should take place on client side.
Additionally, Django's FormWizard uses either a Cookie storage backend, or a Session storage backend in order to store information, which makes the navigation between steps and modifying previous stored data pretty trivial.
I hope I helped you in your decision! A lot more information can be found of course in the Django documentation of FormWizard in the link I provided above.

Related

How can a model be cleared (Django ) when moving to another page or reloading the current one?

Good day!
I ask for help please, this is very important for me, can someone tell me something.
I have a page template.
And a view made for it.
I also have code with various operations on models in this view.
When there is a transition on this page - representation, I have a form in which I place the processed data.
When I reload the page or go to another page - view, the data in the form remains unchanged because I use a model specially made for this as the data source for the model.
I need to clear the model or do some other operation when I leave this page to another one or reload it.

Using Django forms with arbitrary elements based on user input

I'm working on a Django (1.11.1) app which allows users to request reimbursement for certain purchases. Part of the request form (using django.forms) is an itemized list of purchases. I could, of course, hard code some number of rows into the form and make users submit a separate form if they need more rows. But that seems rather inelegant.
My preferred solution would be to allow users to add rows as necessary via JavaScript, then handle that dynamically in forms. However, everything I've found on the subject relates to situations where the number of elements required can be determined at the time the form is rendered to HTML. It isn't clear to me how to apply such an approach to my situation.
As dynamically adding form elements is extremely common, I'm a bit surprised that such functionality isn't baked into Django already.
By the way, as this is intended to be an incredibly simple app, I don't want a solution that will require a lot of work. If there's no easy solution, it'd be better to just hard-code the form HTML directly into the template.
Of course it is covered by django.
You need to use formset https://docs.djangoproject.com/en/1.11/topics/forms/formsets/
And then in the template you need to add more forms dinamically to that formset, better via javascript. Dynamically adding a form to a Django formset with Ajax
It could result hard to understand all the options that django provides with formsets, but it's quite powerful and the simplest way.

Editable unstructured pages

I'm building a small site framework for a set of sites that are likely to have quite a few unstructured pages - meaning they have:
Slightly different layouts per page
Lots of one-off text
None/very little generated content from models
I would like to allow clients to edit the content of these pages through my admin UI (I'm using Django for this project), but with the requirement that they are not exposed to the page HTML and are only able to edit parts of the page that I've specified as fields; for example:
Titles
A few blocks of text content
Perhaps some blocks of predefined image locations
PDF files that need embedding
Where these fields vary significantly between pages.
The layout, and what fields these pages require would be specified by the developer, so there's no need to dynamically generate much for this.
The 'best' idea I've had so far is to serialise these blocks of content once they've been edited by the user and store them in a 'Pages' table/model in my relational database, or just throw MongoDB or similar at it.
Conceptually, how would you implement such pages? As mentioned, I'm using Django so any implementation suggestions specific to Django are welcome, but general high-level ideas would be great too.
I would implement a ContentBlock model, which has .kind (header, text, image, pdf) and a .data, which would house the content (if text) or path to an uploaded pdf/image/etc. Presumably then you'd hardcode the pages with the appropriate blocks defined - I'd just use hardcoded slugs, eg, 'home-title', 'home-intro', 'about-title', 'about-text', 'about-right-photo', etc.
I would suggest not using Django's admin interface. It's much more suited to editing homogenous, non-business-logic models. I'd just add an edit view that renders the appropriate form fields for the blocks instead - html editor, file upload, etc. It's possible to do that in the django admin, but in my experience it's not worth the trouble - plus, if you do your own edit view, you can have it use the same base templates as the rest of the site, which IMO is a better user experience.
Here are a couple of apps which do that for you:
django-generic-flatblocks
django-boxes
Along with django-frontendadmin, it's super cool.

Django strategy for automatically suggesting matching content

I'm looking at porting a custom-written PHP CMS into Django. One of the features the CMS currently has is an image upload function. I write an article, tag it with information, then choose a photo for it. If the system has any photos which have been added to articles with tags in common with the new one, it will suggest the photo for that article too. If there are no matches then a new image can be added.
In case this doesn't make sense, let's say I tag an article as Bruce Springsteen, The Beatles and Led Zeppelin. Next time I add an article with the tag The Beatles, it should suggest I use the image added for the first article.
What would be the best Django-applicable way to implement this? I've looked at the Photologue app and have integrated it, and I know it has tagging support (the problem here is that I'm using django-taggit, whereas Photologue supports django-tagging). One approach could be simply building it myself -- when a user uploads an article, I run a hook after they save it to associate the tags with the image. I'm just not sure how to then autosuggest an image in the admin tools based on that info.
Any ideas/approaches greatly appreciated.
This is almost certainly something you're going to have to build yourself. Django has a moderate number of libraries out there (that you've clearly already found). Unlike other solutions, it doesn't have a lot of things that get you 100% to your desired solution (whereas something like Drupal might get you 100% of the way there).
What you will probably need to do (at a high level) is something like this:
Create an AJAX view that takes the current tags as an argument and does a query on the existing posts to see what tags match and returns images from those posts.
Use jQuery/javascript on your view to call your AJAX view on the page as tags are added
Use jQuery to update a <div> on your page and show all the images that your view returned
Here is a similar example that might help get you started.
You might look into django-ajax as a helper library for your requests, but it definitely isn't necessary.
The hook between the your image module and any other django module can be implemented using django's contenttypes framework which also provides some useful instance methods for returning related/hooked objects.

Should I modify/extend the admin interface, or write my own CRUD views/templates?

I'm trying to write a simple CRM app in Django; partly as a learning exercise and partly for in-house use.
My schema is slightly complex, as rather that have a single Contact model (with a home phone, work phone, home email, etc.), I have stripped down Cntact model plus a Phone model, an Email model, etc., with a ForeignKey pointing back to a Contact. The point is to let Contacts have an arbitrary number of phone numbers, email addresses, etc. Simple, right?
I have some working views and templates for displaying the data - no issues there. And with only a very small amount of poking at admin.py I have a um...eight different TabularInlines set up, and the admin interface works to create and edit the data...but it's ugly and clunky to the point of unusability, and of course there's no conception of permissions or anything. I'm also not really a fan of having a completely different interface for displaying and searching through the data than for editing and adding contacts...I'd like as much as possible to be done inline, so that I can search for a name, look at the record, click "add note", have it popup a form, fill in the details, click submit, and be done, all with AJAXy goodness so there's no page reloads.
Question: Should I plug away at modifying the admin interface to try and make it usable for a user-facing app? And if so, can anyone point me to a good guide or example where someone has really changed the admin interface to make it work for user-facing CRUD operations?
Or should I just go ahead and write my own CRUD views? And if so, can anyone point me to a good guide or example where someone has written custom CRUD views that work with lots of ForeignKeys and inlines? Ideally I want a form that displays a single Contact, all his Email records, plus a blank form to add a new Email record, plus a button to add more blank forms, plus his Phone records, plus a blank form, and so on for all 8 of my associated models.
(Or am I thinking about this all wrong? Any advice appreciated.)
For our intranet, we use ModelAdmin subclasses (not mounted on the admin site via admin.site.register) for most of our C(R)UD views. By using custom templates for the views, it doesn't look like Django admin at all. What is very convenient though, is that it already handles all the validation/saving for us.
In general, I found admin-"hacking" quite useful to quickly write up C(R)UD views and usually with relatively small changes to your ModelAdmin subclass, you can make it work for your use case.
So I'd vote for use ModelAdmin, but not the one you use in admin, hook a different template and come up with some fancy CSS.
I successfully created a software on top of admin.
The admin hooks (these days) allow very fine-grained customizations, i.e. in general you only need to touch what you want to change.
The changes can go from a trivial cosmetic adjustment to a complete swap-out:
If you provide templates/admin/base.html your admin site can look any way you like. And of course, a navigation bar at the top could include links to some of your own views. Watch out not to hardcode URLs in your links, always reverse.
You can overload ModelAdmin's "change_view", "changelist_view" etc. and swap them for your own views. For example I replaced a default changelist and its simple filtering with a search interface that allows dynamic queries to be built, result columns to be customized by the user, and loading/saving of these searches. That didn't affect any of the other views of that ModelAdmin.
Overloading a ModelAdmin's "get_urls()" let's you rewrap existing admin urls to go to your own views. I did the latter for one model where I wanted the simple Add screen to be replaced by a totally customized Wizard (only leaning on ModelForm).
Don't forget the simplest approach, esp. regarding your "AJAXy goodness": Just define "css" and "js" in your ModelAdmin's Meta. Want to move an inline from the bottom to sit between third and fourth field, and that's not possible via parameters? A one-liner in jquery.
Check out "django-grappelli" for an example of how to improve admin look and feel.
What did you mean by "and of course there's no conception of permissions or anything"?