How to change browse button to look like modern drag&drop? - python

I have created a django site, django site is working in this way. You go to the site, upload document with data and you get some results. You upload excel file, and you download excel file. In background I used pandas for calculations. In the end you can see code.
I have left one thing to finish. I want to create drag&drop for upload document. Chech picture 1, as I understand this is already drag&drop, just doesn't look as I would like to. I want to look like in picture 2.
Picture 1: Current
Picture 2: I would like to look like this.
Can I change the look that you seen on first image without using js?
This is html that I have and output is shown in picture 1...
{% extends "base.html" %}
{% load static %}
{% block content %}
<form action="{% url "cal" %}" method="post" enctype="multipart/form-data" class="dropzone">
{% csrf_token %}
{{ message }}
<p>{{ form.non_field_errors }}</p>
<p>{{ form.docfile.label_tag }} {{ form.docfile.help_text }}</p>
<p>
{{ form.docfile.errors }}
{{ form.docfile }}
</p>
<p><input type="submit" value="Upload and Download!"/></p>
</form>
{% endblock content %}
This is function in views
def OnlyCAL(request):
if request.method == "POST":
form = DocumentForm(request.POST, request.FILES)
if form.is_valid():
output = io.BytesIO()
newdoc = request.FILES['docfile']
#pandas calculations
response = HttpResponse(
output, content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
response['Content-Disposition'] = 'attachment; filename=%s' % filename
return response
else:
form = DocumentForm()
return render(request, 'cal.html', { 'form': form, 'page_title':page_title })

I think the best option for you is to use dropzone.js. You can find documentation here.
You should include .js and .css. Also you can customize dropzone view on your own as described here (example of customizing dropzone in combination with Django, maybe will be useful for you)
You can try this (.js and .css files included directly in your template just for example, you can include easily include it in other way):
{% extends "base.html" %}
{% load static %}
<script src="https://unpkg.com/dropzone#5/dist/min/dropzone.min.js"</script>
<link rel="stylesheet" href="https://unpkg.com/dropzone#5/dist/min/dropzone.min.css" type="text/css" />
{% block content %}
<form id="dropZoneForm" action="{% url "cal" %}" method="post" enctype="multipart/form-data" class="dropzone needsclick dz-clickable">
{% csrf_token %}
<input type="hidden" name="abc" value="i am hidden value">
<div class="fallback">
<input name="file" type="file"/>
</div>
<input type="submit" id="submit-all" value="Upload and Download" class="custom-button" style="float: right">
</form>
{% endblock content %}

Related

Possibility to fill in form OR upload file in Django

I am currently trying to make a platform for Formula One statistics. Which of course should be able to add circuits (my first form). And I let Django make the form so that works, but I would like the option to fill in manually or upload a file so he will parse the code.
Here is my form:
class CircuitForm(forms.ModelForm):
class Meta:
model = Circuit
exclude = []
Here is the page that is displayed:
{% extends "base.html" %}
{% block content %}
<h1>Welcome in the uploads</h1>
<h2>You can add a single circuit here</h2>
<form method="post" enctype="multipart/form-data">
<table>
{{ form }}
</table>
<br><br>
<h3>Or you can upload a file for bulk-uploading:</h3>
<input type="file" name="circuitsFile" value="Upload a file">
<br><br><br><br>
<button class="button" type="submit">Submit</button>
</form>
{% endblock %}
When you press the submit button, it doesn't do anything since the other fields need to be filled in first
If anyone knows the solution, I'd like to hear it :)

Add custom admin add page/template in Django

In my current Django project I need to implement one admin page that loads some asynchronous data with AngularJS to fill the form fields. Some form fields (on client side) will be updated by AngularJS.
My question is: What's the right approach to add this complex add/change page of my AdminModel? Should I create a pure json / AngularJS client side page?
The forms fields will be the same of my Model field, so I would like to use ModelForm.
I tried with:
class ContractAdmin(admin.ModelAdmin):
add_form_template = "admin/add_contract.html"
and then in my contract.html template:
{% extends "admin/base_site.html" %}
{% load i18n admin_urls admin_static admin_modify %}
{% block content %}
<form action="" method="post">
{% csrf_token %}
{{ form.as_p }} <!-- this produces nothing -->
<br />
<br />
<input type="submit" value="Submit" />
</form>
{% endblock %}

Django HTML5 -- downloading a file

This is my .html file. It enables the user to upload files and see the list of files uploaded, and download the files on the list -- or is supposed to!
The problem is that document.docfile.url (docfile is the FileField object) doesn't return the desired file path. The desired filepath contains 'media' but the returned file path is myapp/list/(...)
My MEDIA_URL is 'media', that is.
I suspect this is an inadequate explanation, so just let me know if you need further information.
<body>
<!-- List of uploaded documents -->
{% if documents %}
<ul>
{% for document in documents %}
<li>{{ document.docfile.name }}
Download</li>
{% endfor %}
</ul>
{% else %}
<p>No documents.</p>
{% endif %}
<!-- Upload form. Note enctype attribute! -->
<form action="{% url "list" %}" method="post" enctype="multipart/form-data">
{% csrf_token %}
<p>{{ form.non_field_errors }}</p>
<p>{{ form.docfile.label_tag }} {{ form.docfile.help_text }}</p>
<p>
{{ form.docfile.errors }}
{{ form.docfile }}
</p>
<p><input type="submit" value="Upload" /></p>
</form>
</body>
This is my views.py:
def list(request):
# Handle file upload
if request.method == 'POST':
form = DocumentForm(request.POST, request.FILES)
if form.is_valid():
newdoc = Document(docfile = request.FILES['docfile'])
newdoc.save()
# Redirect to the document list after POST
return HttpResponseRedirect(reverse('myapp.views.list'))
else:
form = DocumentForm() # An empty, unbound form
# Load documents for the list page
documents = Document.objects.all()
# Render list page with the documents and the form
return render_to_response(
'myapp/list.html',
{'documents': documents, 'form': form},
context_instance=RequestContext(request)
)

Seeking complete example of class based views crud, including template

Django 1.3 documentation on class based views is seeming like a treasure hunt. How to write the class is clear enough... but what kind of template code matches each generic class? Would someone provide a complete example soup to nuts? Here's what I have so far:
urls.py
(r'^brand_create2$', BrandCreate.as_view()),
views.py
from django.views.generic import CreateView
#login_required
class BrandCreate(CreateView):
template_name = 'generic_form_popup.html'
context_object_name = "brand_thingie"
#queryset = models.Brand.objects.all()
success_url = '/'
generic_form_popup.html
????
In this case I'm exploring if it is worth learning the new style, given the older style still works:
urls.py
url(r'^brand_create1$', 'coat.views.brand_create'),
views.py
class formBrand(forms.ModelForm):
class Meta:
model = models.Brand
exclude = ('')
#login_required
def brand_create(request):
form = formBrand
if request.method == 'POST':
form = formBrand(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect('/')
passed = dict(
form=form,
MEDIA_URL = settings.MEDIA_URL,
STATIC_URL = settings.STATIC_URL)
return render_to_response('generic_form_popup.html',
passed, context_instance=RequestContext(request))
generic_form_popup.html
{% extends 'head-plain.html' %}
{% block title %}{% endblock %}
{% block headstuff %}{% endblock %}
{% block content %}
<form action="{{ action }}" method="post">
{% csrf_token %}{{ form.as_p }}
<input type="submit" value="Submit" /> </form>
{% endblock %}
CreateView inherits from ModelFormMixin, which in turn inherits from FormMixin and SingleObjectMixin.
SingleObjectMixin provides the object template context variable, which is probably not going to be any use in the case of CreateView:
object: The object that this view is displaying. If context_object_name is specified, that variable will also be set in the context, with the same value as object.
But FormMixin provides the form context variable:
form: The form instance that was generated for the view.
Thus, you can refer to the documentation to display a form with a template:
<form action="/contact/" method="post">{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Submit" />
</form>
Which means that the very template you posted should almost work with the class based view:
{% extends 'head-plain.html' %}
{% block title %}{% endblock %}
{% block headstuff %}{% endblock %}
{% block content %}
<form action="" method="post">
{% csrf_token %}{{ form.as_p }}
<input type="submit" value="Submit" /> </form>
{% endblock %}
I removed {{ action }} because it is not part of the context, neither in the old-style view, neither with the class based view, so it doesn't make any sense. You should know that if action="" then the browser will submit to the current url. You can force the action to the current url with action="{{ request.path }}" or you can specify another url with the url template tag.
Suppose apply the best practice of naming url patterns, by changing:
(r'^brand_create2$', BrandCreate.as_view()),
to:
(r'^brand_create2$', BrandCreate.as_view(), name='band_create'),
Then you can use: action="{% url band_create %}".
You can also customize further:
<form action="/contact/" method="post">
{% csrf_token %}
{{ form.non_field_errors }}
<div class="fieldWrapper">
{{ form.subject.errors }}
<label for="id_subject">Email subject:</label>
{{ form.subject }}
</div>
<div class="fieldWrapper">
{{ form.message.errors }}
<label for="id_message">Your message:</label>
{{ form.message }}
</div>
<div class="fieldWrapper">
{{ form.sender.errors }}
<label for="id_sender">Your email address:</label>
{{ form.sender }}
</div>
<div class="fieldWrapper">
{{ form.cc_myself.errors }}
<label for="id_cc_myself">CC yourself?</label>
{{ form.cc_myself }}
</div>
<p><input type="submit" value="Send message" /></p>
</form>
Of course, the fields available in the form depend on your Model.

django - How can I render a template I use everywhere in my webpage?

I'm using django 1.2.4.
I have a template for login in registration/login.html (wich action is django.contrib.auth.views.login) and I want to include it on everypage. I created a block on my base.html as I do for every template. The thing is the browser doesn't recognize this login block and I think it is because I only render a template for each view, I am not rendering this login template.
Here is my folder structure:
/templates/
base.html
/myapp/
object_list.html
...
/registration/
login.html
...and here is my login.html:
{% extends "base.html" %}
{% block mylogin %}
<div class="horizontal">
{% if form.errors %}
<p>Your username and password didn't match. Please try again.</p>
{% endif %}
<form action="{% url django.contrib.auth.views.login %}" method="post">
{% csrf_token %}
<div class="login_box">
<div class="login_text">{{ form.username.label_tag }}</div><div class="login_input">{{ form.username }}</div>
<div class="password_text">{{ form.password.label_tag }}</div><div class="password_input">{{ form.password }}</div>
<input id="button_login" type="submit" value="" />
</div>
</form>
</div>
{% endblock %}
...and in my base.html I have:
<div id="some_div">
{% block mylogin %} {% endblock %}
</div>
I have a basestyle.css included in base.html and the other templates inherit correctly too... it seems to be a block problem...
So.. how can I render this template for every view??
Thank you
I think you are looking for the include tag. This way you can include your login html snippet in your base.html :
{% include "/registration/login.html" %}
What I really need was to create a templatetag in templatetags/mytags.py, where I define a function called get_login wich looks like this:
#register.inclusion_tag('registration/login.html', takes_context=True)
def get_login(context):
...
return {'formLogin': mark_safe(AuthenticationForm())}
...and in base.html:
{% load mytags %}{% get_login %}
The problem now is that the template (registration/login.html) doesnt recognize '{{ formLogin.username }}','{{ formLogin.password }}' and so on.
What am I missing?
Update 1:
mark_safe returns an instance of django.utils.safestring.SafeString, not a form.
Use (AuthenticationForm() instead of mark_safe(AuthenticationForm()) and it works!

Categories

Resources