Im using Django report builder, and im trying to export one of my created reports as a xls file, this is my function in views.py :
from django.shortcuts import render, get_object_or_404
from django.http import HttpResponseRedirect
from django.views.generic import View
from django.core.urlresolvers import reverse
from django.contrib.auth.models import User
from django.shortcuts import render_to_response
from django.template import RequestContext
from django.utils import timezone
from ..form import UsersForm, CostItemsForm, GroupsForm, SubGroupsForm, SubGroups2Form, CostElementsForm, RequestsForm
from ..models import Groups, CostItems, Requests, CostElements, Positions, ItemChangeLogs, ElementChangeLogs
from datetime import date, datetime
from report_builder.models import Report
from report_utils.mixins import DataExportMixin, generate_filename
class DownloadFileView(DataExportMixin, View):
def dispatch(self, *args, **kwargs):
return super(DownloadFileView, self).dispatch(*args, **kwargs)
def process_report(self, report_id, user_id,
file_type, to_response, queryset=None):
report = get_object_or_404(Report, pk=2)
user = request.user
if not queryset:
queryset = report.get_query()
display_fields = report.get_good_display_fields()
objects_list, message = self.report_to_list(
queryset,
display_fields,
user,
preview=False,)
title = re.sub(r'\W+', '', report.name)[:30]
header = []
widths = []
for field in display_fields:
header.append(field.name)
widths.append(field.width)
if to_response:
return self.list_to_xlsx_response(
objects_list, title, header, widths)
So, im calling this view from a template :
{% extends 'cost_control_app/base_cost_control_app.html' %}
{% block contentsubbase %}
{% load widget_tweaks %}
<div class="center-panel">
<h3>Reports</h3>
{% csrf_token %}
<br>
<div class="table-responsive">
<a href="{% url 'cost_control_app:report_download' %}" >Export</a>
</div>
</div>
{% endblock contentsubbase %}
And this is my urls.py that connects all :
from django.conf.urls import include, url, patterns
from django.contrib.auth import views as auth_views
from django.contrib.auth.views import login, logout
from .views import views
urlpatterns = patterns(
'',
url(r'^reports/download/$', views.DownloadFileView.as_view(), name = "report_download"),
)
thing is, is not working, when i click the a label called "Export" it takes me to the empty template but no save file dialog or nothing....any idea please ?
Thanks in advance
Found it (for anyone who has the same issue sometime), i was missing the def get where parameters where set, this is the views.py updated, put some default values as an example :
class DownloadFileView(DataExportMixin, View):
def process_report(self, report_id, user_id,
file_type, to_response, queryset=None):
report = get_object_or_404(Report, pk=report_id)
user = User.objects.get(pk=user_id)
if not queryset:
queryset = report.get_query()
display_fields = report.get_good_display_fields()
objects_list, message = self.report_to_list(
queryset,
display_fields,
user,
preview=False,)
title = re.sub(r'\W+', '', report.name)[:30]
header = []
widths = []
for field in display_fields:
header.append(field.name)
widths.append(field.width)
if to_response:
return self.list_to_xlsx_response(
objects_list, title, header, widths)
def get(self, request, *args, **kwargs):
report_id = 2
file_type = 'xls'
user_id = 2
return self.process_report(
report_id, user_id, file_type, to_response=True)
Related
I have some templates in a django project. I'm trying to save them in the the url with a post request even though I specify it in the html document.
Here's my views.py
`
from django.shortcuts import render
from django.http import HttpResponse, HttpResponseRedirect
from .forms import WcaForm, IdForm
from . import wcaScraper
# Create your views here.
def id(response):
form = IdForm(response.GET)
return render(response, "main/id.html", {"form": form})
def idresults(response):
print(response.method)
if response.method == "GET":
print(wcaScraper.getDataByName(response.GET.get('name')))
return render(response, "main/nameresults.html", {"ids": wcaScraper.getDataByName(response.GET.get('name'))})
def search(response):
form = WcaForm(response.GET)
return render(response, "main/search.html", {"form": form})
def results(response):
wcaData = wcaScraper.getDataById(response.GET.get('id'))
variablePassed = {
"id": response.GET.get('id'),
"single3": wcaData[0].single,
"avg3": wcaData[0].avg,
"single2": wcaData[1].single,
"avg2": wcaData[1].avg,
"single4": wcaData[2].single,
"avg4": wcaData[2].avg,
"single5": wcaData[3].single,
"avg5": wcaData[3].avg,
"single6": wcaData[4].single,
"avg6": wcaData[4].avg,
"single7": wcaData[5].single,
"avg7": wcaData[5].avg,
"blind3single": wcaData[6].single,
"blind3avg": wcaData[6].avg,
"fmsingle": wcaData[7].single,
"fmavg": wcaData[7].avg,
"ohsingle": wcaData[8].single,
"ohavg": wcaData[8].avg,
"clocksingle": wcaData[9].single,
"clockavg": wcaData[9].avg,
"megasingle": wcaData[10].single,
"megaavg": wcaData[10].avg,
"pyrasingle": wcaData[11].single,
"pyraavg": wcaData[11].avg,
"skewbsingle": wcaData[12].single,
"skewbavg": wcaData[12].avg,
"squaresingle": wcaData[13].single,
"squareavg": wcaData[13].avg,
"blind4single": wcaData[14].single,
"blind4avg": wcaData[14].avg,
"blind5single": wcaData[15].single,
"blind5avg": wcaData[15].avg,
"multisingle": wcaData[16].single,
"multiavg": wcaData[16].avg,
}
return render(response, "main/results.html", variablePassed)
`
And my html template
<html>
<h1>Search by name</h1>
<form method="get" action="/idresults">
{% csrf_token %} {{form}}
<button type="submit">Search</button>
</form>
<p>or</p>
Search by WCA Id
</html>
I tried printing the method and I got `GET
But the url looks like this
http://localhost:8000/idresults/?csrfmiddlewaretoken=v1jXO1Tei1eU0l8FbgF49qeJU5zKJlTQUUkggmW0oYgrG5WcLOvJhBb08PBY3klg&name=zemdegs
Your url does not appear as a POST, but as a GET. If your problem is the token, just remove the {%csrf_token%} from your template.
I am attempting the solution mentioned in this stack overflow post (Adding a button to Wagtail Dashboard) however the solution might be outdated, or at least it doesn't work for me and I'm unsure why.
Goal: Be able to export a object's data to csv
First, the button HTML code had to be slightly adjusted to be formatted correctly like so:
{% extends "modeladmin/index.html" %}
{% block header_extra %}
<div class="right">
<div class="addbutton" style="margin-left: 2em;">
{% include "modeladmin/includes/button.html" with button=view.button_helper.export_button %}
My button
</div>
</div>
{{ block.super }}{% comment %}Display the original buttons {% endcomment %}
{% endblock %}
and then I copied and pasted the views and helper functions:
from django.contrib.auth.decorators import login_required
from django.urls import reverse
from django.utils.decorators import method_decorator
from django.utils.functional import cached_property
from django.utils.translation import ugettext as _
from wagtail.contrib.modeladmin.helpers import AdminURLHelper, ButtonHelper
from wagtail.contrib.modeladmin.views import IndexView
class ExportButtonHelper(ButtonHelper):
"""
This helper constructs all the necessary attributes to create a button.
There is a lot of boilerplate just for the classnames to be right :(
"""
export_button_classnames = ['icon', 'icon-download']
def export_button(self, classnames_add=None, classnames_exclude=None):
if classnames_add is None:
classnames_add = []
if classnames_exclude is None:
classnames_exclude = []
classnames = self.export_button_classnames + classnames_add
cn = self.finalise_classname(classnames, classnames_exclude)
text = _('Export {}'.format(self.verbose_name_plural.title()))
return {
'url': self.url_helper.get_action_url('export', query_params=self.request.GET),
'label': text,
'classname': cn,
'title': text,
}
class ExportAdminURLHelper(AdminURLHelper):
"""
This helper constructs the different urls.
This is mostly just to overwrite the default behaviour
which consider any action other than 'create', 'choose_parent' and 'index'
as `object specific` and will try to add the object PK to the url
which is not what we want for the `export` option.
In addition, it appends the filters to the action.
"""
non_object_specific_actions = ('create', 'choose_parent', 'index', 'export')
def get_action_url(self, action, *args, **kwargs):
query_params = kwargs.pop('query_params', None)
url_name = self.get_action_url_name(action)
if action in self.non_object_specific_actions:
url = reverse(url_name)
else:
url = reverse(url_name, args=args, kwargs=kwargs)
if query_params:
url += '?{params}'.format(params=query_params.urlencode())
return url
def get_action_url_pattern(self, action):
if action in self.non_object_specific_actions:
return self._get_action_url_pattern(action)
return self._get_object_specific_action_url_pattern(action)
class ExportView(IndexView):
"""
A Class Based View which will generate
"""
def export_csv(self):
data = self.queryset.all()
response = ...
return response
#method_decorator(login_required)
def dispatch(self, request, *args, **kwargs):
super().dispatch(request, *args, **kwargs)
return self.export_csv()
class ExportModelAdminMixin(object):
"""
A mixin to add to your model admin which hooks the different helpers, the view
and register the new urls.
"""
button_helper_class = ExportButtonHelper
url_helper_class = ExportAdminURLHelper
export_view_class = ExportView
def get_admin_urls_for_registration(self):
urls = super().get_admin_urls_for_registration()
urls += (
url(
self.url_helper.get_action_url_pattern('export'),
self.export_view,
name=self.url_helper.get_action_url_name('export')
),
)
return urls
def export_view(self, request):
kwargs = {'model_admin': self}
view_class = self.export_view_class
return view_class.as_view(**kwargs)(request)
and then I added the ModelAdmin to the hooks. I'm able to see the button however it doesn't function as it's supposed to (exporting the csv). In fact, it does absolutely nothing (the href is # after all) and I feel like I'm missing some steps.
I used the same implementation as you.
I guess that you are having problems in the def export_csv(self) method
here my implementation
from djqscsv.djqscsv import render_to_csv_response
class ExportView(IndexView):
model_admin = None
def export_csv(self) -> dict:
if (self.model_admin is None) or not hasattr(
self.model_admin, "csv_export_fields"
):
data = self.queryset.all().values()
else:
data = self.queryset.all().values(*self.model_admin.csv_export_fields)
return render_to_csv_response(data)
#method_decorator(login_required)
def dispatch(self, request: HttpRequest, *args: list, **kwargs: dict) -> dict:
super().dispatch(request, *args, **kwargs)
return self.export_csv()
csv_export_fields can be added to your model admin to specify which fields you want to export
here I am adding the HTML file:
{% extends "modeladmin/index.html" %}
{% block header_extra %}
{% include 'modeladmin/includes/button.html' with button=view.button_helper.export_button %}
{{ block.super }}
{% endblock %}
your admin.py
class MyModelAdmin(ModelAdmin, ExportModelAdminMixin):
model = MyModel
menu_icon = 'tag'
menu_order = 200
index_template_name = "wagtailadmin/export_csv.html"
csv_export_fields = [ "field_name","field_name_1", ]
list_display = ('first_name', 'last_name'')
search_fields = ('first_name', 'last_name',)
I want to use django-import-export's forms to implement the import feature for regular users, so it needs to be outside the admin section.
So far, all the implementations I have found are about
a) extending the feature inside the admin or
b) reimplementing the default views outside the admin.
But since the default forms work perfectly (specially the ConfirmImportForm that shows a diff between old records and new records attempting to be imported) I would like to subclass them as part of my project (outside admin) without reimplementing the whole view's logic, if such thing is even possible.
So far I tried (foolishly, I'm afraid) to subclass the import_export.admin.ImportMixin as two separated class views to import a model Period with resource PeriodResource. The methods import_action and process_import were reimplemented (basically copy and paste the same code and eliminating any code using self.site_admin) as View.get() and View.post():
# staging/views.py
from django.http import HttpResponseRedirect, HttpResponse
from django.urls import reverse
from django.views import generic
from django.template.response import TemplateResponse
from django.utils.translation import gettext_lazy as _
from django.utils.encoding import force_text
from import_export.forms import ConfirmImportForm
from import_export.signals import post_import
import import_export.admin
from .models import Period
from .resources import PeriodResource
class PeriodImportView(import_export.admin.ImportMixin, generic.View):
"""
Subclassing of ImportMixin as a generic View implementing ImportForm
"""
#: template for import view
import_template_name = 'period/import.html'
#: resource class
resource_class = PeriodResource
#: model to be imported
model = Period
def get_confirm_import_form(self):
'''
Get the form type used to display the results and confirm the upload.
'''
return ConfirmImportForm
def get(self, request, *args, **kwargs):
"""
Overriding the GET part of ImportMixin.import_action method to be used without site_admin
"""
resource = self.get_import_resource_class()(**self.get_import_resource_kwargs(request, *args, **kwargs))
context = self.get_import_context_data()
import_formats = self.get_import_formats()
form_type = self.get_import_form()
form = form_type(import_formats,
request.POST or None,
request.FILES or None)
# context.update(self.admin_site.each_context(request))
context['title'] = _("Import")
context['form'] = form
context['opts'] = self.model._meta
context['fields'] = [f.column_name for f in resource.get_user_visible_fields()]
# request.current_app = self.admin_site.name
return TemplateResponse(request, [self.import_template_name],
context)
def post(self, request, *args, **kwargs):
"""
Overriding the POST part of ImportMixin.import_action method to be used without site_admin
"""
resource = self.get_import_resource_class()(**self.get_import_resource_kwargs(request, *args, **kwargs))
context = self.get_import_context_data()
import_formats = self.get_import_formats()
form_type = self.get_import_form()
form = form_type(import_formats,
request.POST or None,
request.FILES or None)
if request.POST and form.is_valid():
input_format = import_formats[
int(form.cleaned_data['input_format'])
]()
import_file = form.cleaned_data['import_file']
# first always write the uploaded file to disk as it may be a
# memory file or else based on settings upload handlers
tmp_storage = self.write_to_tmp_storage(import_file, input_format)
# then read the file, using the proper format-specific mode
# warning, big files may exceed memory
try:
data = tmp_storage.read(input_format.get_read_mode())
if not input_format.is_binary() and self.from_encoding:
data = force_text(data, self.from_encoding)
dataset = input_format.create_dataset(data)
except UnicodeDecodeError as ex1:
return HttpResponse(_(u"<h1>Imported file has a wrong encoding: %s</h1>" % ex1))
except Exception as ex2:
return HttpResponse(_(u"<h1>%s encountered while trying to read file: %s</h1>" % (type(ex2).__name__, import_file.name)))
result = resource.import_data(dataset, dry_run=True,
raise_errors=False,
file_name=import_file.name,
user=request.user)
context['result'] = result
if not result.has_errors() and not result.has_validation_errors():
context['confirm_form'] = self.get_confirm_import_form()(initial={
'import_file_name': tmp_storage.name,
'original_file_name': import_file.name,
'input_format': form.cleaned_data['input_format'],
})
# context.update(self.admin_site.each_context(request))
context['title'] = _("Import")
context['form'] = form
context['opts'] = self.model._meta
context['fields'] = [f.column_name for f in resource.get_user_visible_fields()]
# request.current_app = self.admin_site.name
return TemplateResponse(request, [self.import_template_name],
context)
class PeriodConfirmImportView(import_export.admin.ImportMixin, generic.View):
"""
Subclassing of ImportMixin as a generic View implementing ConfirmImportForm
"""
#: template for import view
import_template_name = 'period/import.html'
#: resource class
resource_class = PeriodResource
#: model to be imported
model = Period
def post(self, request, *args, **kwargs):
"""
Perform the actual import action (after the user has confirmed the import)
"""
# if not self.has_import_permission(request):
# raise PermissionDenied
confirm_form = ConfirmImportForm(request.POST)
if confirm_form.is_valid():
import_formats = self.get_import_formats()
input_format = import_formats[
int(confirm_form.cleaned_data['input_format'])
]()
tmp_storage = self.get_tmp_storage_class()(name=confirm_form.cleaned_data['import_file_name'])
data = tmp_storage.read(input_format.get_read_mode())
if not input_format.is_binary() and self.from_encoding:
data = force_text(data, self.from_encoding)
dataset = input_format.create_dataset(data)
result = self.process_dataset(dataset, confirm_form, request, *args, **kwargs)
tmp_storage.remove()
self.generate_log_entries(result, request)
self.add_success_message(result, request)
post_import.send(sender=None, model=self.model)
url = reverse('staging:index')
return HttpResponseRedirect(url)
and then just show the forms in the template:
# staging/templates/period/import.html
{% if confirm_form %}
<form action="{% url 'staging:confirm_import_period' %}" method="POST">
{% csrf_token %}
{{ confirm_form.as_p }}
<p>
{% trans "Below is a preview of data to be imported. If you are satisfied with the results, click 'Confirm import'" %}
</p>
<div class="submit-row">
<input type="submit" class="default" name="confirm" value="{% trans "Confirm import" %}">
</div>
</form>
{% else %}
<form action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
<p>
{% trans "This importer will import the following fields: " %}
<code>{{ fields|join:", " }}</code>
</p>
<fieldset class="module aligned">
{% for field in form %}
<div class="form-row">
{{ field.errors }}
{{ field.label_tag }}
{{ field }}
{% if field.field.help_text %}
<p class="help">{{ field.field.help_text|safe }}</p>
{% endif %}
</div>
{% endfor %}
</fieldset>
<div class="submit-row">
<input type="submit" class="default" value="{% trans "Submit" %}">
</div>
</form>
{% endif %}
and my urls.py looks like this:
# staging/urls.py
from django.urls import path
from .views import PeriodIndexView, PeriodImportView, PeriodConfirmImportView
app_name = 'staging'
urlpatterns = [
path('period/', PeriodIndexView.as_view(), name='index'),
path('period/import/', PeriodImportView.as_view(), name='import_period'),
path('period/confirm_import/', PeriodConfirmImportView.as_view(), name='confirm_import_period'),
]
So far it works as intended, but this approach is so tightly coupled to the internal implementation of ImportMixin that I am afraid it will not survive any version upgrade of django-import-export.
Is there any way to achieve that without reimplementing the whole import_action and process_import methods?
After a lot of try and error I gave up on avoiding the re-implementation of methods import_action and process_import from import_export.admin.ImportMixin. Instead, I created my own mixins subclassing import_export.admin.ImportMixin and django.views.generic.View and removing all references to self.site_admin from methods import_action and process_import into equivalent methods get() and post().
# staging/views.py
from django.http import HttpResponseRedirect, HttpResponse
from django.urls import reverse
from django.views import generic
from django.template.response import TemplateResponse
from django.utils.translation import gettext_lazy as _
from django.utils.encoding import force_text
from import_export.forms import ConfirmImportForm
from import_export.signals import post_import
import import_export.admin
from .models import Period
from .resources import PeriodResource
class ImportView(import_export.admin.ImportMixin, generic.View):
"""
Subclassing of ImportMixin as a generic View implementing ImportForm
"""
#: template for import view
import_template_name = 'import.html'
#: resource class
resource_class = None
#: model to be imported
model = None
def get_confirm_import_form(self):
'''
Get the form type used to display the results and confirm the upload.
'''
return ConfirmImportForm
def get(self, request, *args, **kwargs):
"""
Overriding the GET part of ImportMixin.import_action method to be used without site_admin
"""
return self.post(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
"""
Overriding the POST part of ImportMixin.import_action method to be used without site_admin
"""
resource = self.get_import_resource_class()(**self.get_import_resource_kwargs(request,
*args,
**kwargs))
context = self.get_import_context_data()
import_formats = self.get_import_formats()
form = self.get_import_form()(import_formats, request.POST or None, request.FILES or None)
if request.POST and form.is_valid():
input_format = import_formats[
int(form.cleaned_data['input_format'])
]()
import_file = form.cleaned_data['import_file']
# first always write the uploaded file to disk as it may be a
# memory file or else based on settings upload handlers
tmp_storage = self.write_to_tmp_storage(import_file, input_format)
# then read the file, using the proper format-specific mode
# warning, big files may exceed memory
try:
data = tmp_storage.read(input_format.get_read_mode())
if not input_format.is_binary() and self.from_encoding:
data = force_text(data, self.from_encoding)
dataset = input_format.create_dataset(data)
except UnicodeDecodeError as ex1:
return HttpResponse(_(u"<h1>Imported file has a wrong encoding: %s</h1>" % ex1))
except Exception as ex2:
return HttpResponse(_(u"<h1>%s encountered while trying to read file: %s</h1>" % (type(ex2).__name__, import_file.name)))
result = resource.import_data(dataset, dry_run=True,
raise_errors=False,
file_name=import_file.name,
user=request.user)
context['result'] = result
if not result.has_errors() and not result.has_validation_errors():
context['confirm_form'] = self.get_confirm_import_form()(initial={
'import_file_name': tmp_storage.name,
'original_file_name': import_file.name,
'input_format': form.cleaned_data['input_format'],
})
# context.update(self.admin_site.each_context(request))
context['title'] = _("Import " + self.get_model_info()[1])
context['form'] = form
context['opts'] = self.model._meta
context['fields'] = [f.column_name for f in resource.get_user_visible_fields()]
# request.current_app = self.admin_site.name
return TemplateResponse(request, [self.import_template_name],
context)
class ConfirmImportView(import_export.admin.ImportMixin, generic.View):
"""
Subclassing of ImportMixin as a generic View implementing ConfirmImportForm
"""
#: template for import view
import_template_name = 'import.html'
#: resource class
resource_class = None
#: model to be imported
model = None
def get_confirm_import_form(self):
'''
Get the form type used to display the results and confirm the upload.
'''
return ConfirmImportForm
def post(self, request, *args, **kwargs):
"""
Perform the actual import action (after the user has confirmed the import)
"""
confirm_form = self.get_confirm_import_form()(request.POST)
if confirm_form.is_valid():
import_formats = self.get_import_formats()
input_format = import_formats[
int(confirm_form.cleaned_data['input_format'])
]()
tmp_storage = self.get_tmp_storage_class()(name=confirm_form.cleaned_data['import_file_name'])
data = tmp_storage.read(input_format.get_read_mode())
if not input_format.is_binary() and self.from_encoding:
data = force_text(data, self.from_encoding)
dataset = input_format.create_dataset(data)
result = self.process_dataset(dataset, confirm_form, request, *args, **kwargs)
tmp_storage.remove()
self.generate_log_entries(result, request)
self.add_success_message(result, request)
post_import.send(sender=None, model=self.model)
url = reverse('{}:{}_index'.format(self.get_model_info()[0], self.get_model_info()[1]))
return HttpResponseRedirect(url)
So now from my custom mixins ImportView and ConfirmImportView y can subclass the specific classes to import my specific models just setting the model and resource_class attributes, which was sort of what I was looking for.
class PeriodImportView(ImportView):
"""
ImportView specific for model Period and resource PeriodResource
"""
#: resource class
resource_class = PeriodResource
#: model to be imported
model = Period
class PeriodConfirmImportView(ConfirmImportView):
"""
ConfirmImportView specific for model Period and resource PeriodResource
"""
#: resource class
resource_class = PeriodResource
#: model to be imported
model = Period
I've been following a tutorial, but making small changes, doesn't allow me to save the form in DB.
However, I know the model is correct because I can save objects from within shell.
I'm not getting any error, after submitting I'm redirected to the home page.
But if I submit form and then go to the admin, I see the registered model, but with no records on in (except the ones saved through shell). Howcome?
models.py:
class TamaniosCantidades(models.Model):
TAMANIOS = (('498', '2" x 2"',), ('499', '3" x 3"',),
('500', '4" x 4"',), ('501', '5" x 5"',))
CANTIDADES = (('100', '50',), ('100', '100',),
('150', '150',))
tamanios = models.CharField(max_length=10, choices=TAMANIOS)
cantidades = models.CharField(max_length=10, choices=CANTIDADES)
forms.py:
from django import forms
from .models import TamaniosCantidades
class TamaniosCantidadesForm(forms.ModelForm):
class Meta:
model = TamaniosCantidades
fields = ['tamanios', 'cantidades']
urls.py:
from . import views
from django.urls import path, include
urlpatterns = [
path('', views.index),
path('productos/', views.productos),
path('post_url/', views.post_treasure, name='post_treasure'),
path('post_url_tamanioscantidades/', views.post_tamanioscantidades, name='post_tamanioscantidades'),
]
views.py:
def index(request):
treasures = Treasure.objects.all()
form = TreasureForm()
tamanioscantidades_form = TamaniosCantidadesForm()
return render(request, 'main_app/index.html', {'treasures': treasures,
'form': form,
'tamanioscantidades_form': tamanioscantidades_form})
def post_tamanioscantidades(request):
tamanioscantidades_form = TamaniosCantidadesForm()
if tamanioscantidades_form.is_valid():
tamanioscantidades_form.save(commit = True)
return HttpResponseRedirect('/')
html:
<div class="row">
<form action="post_url_tamanioscantidades/" method="post">
{% csrf_token %}
{{ tamanioscantidades_form.as_p }}
<input type="submit" value="Submit"/>
</form>
</div>
def post_tamanioscantidades(request):
tamanioscantidades_form = TamaniosCantidadesForm()
if tamanioscantidades_form.is_valid():
tamanioscantidades_form.save(commit = True)
return HttpResponseRedirect('/')
This method creates a blank TamaniosCantidadesForm, which isn't valid, so it never gets saved.
You probably want to do something like TamaniosCantidadesForm(request.POST), to actually fill in the form with the submitted data.
I would like to upload a file, parse it to .txt and then store it in the disk via a django application. I've tried quiet a few things that didn't work. First I want to make the storage work. Here's my code. I would appreciate any help.
Index.html
<form name='F' action='AjoutTelechargement' method='POST'
enctype='multipart/form-data'>
{% csrf_token %}
<input type="file" name="filedir" style="color:white" size="100" >
<input type="submit" class="btn .btn-ajouter btn-xl page-scroll"
value="Ajouter" />
<script type="text/javascript" src="/media/js/jquery-1.10.2.min.js">
</script>
<script>
function myFun() {
$.get('AjoutTelechargement/'
, "value":"get_the_value_from_web"}
, function(ret) {
return ret;
});
}
models.py
from django.db import models
from django.core.files.storage import FileSystemStorage
key_store = FileSystemStorage(location='myFiles/')
class FileUpload(models.Model):
file = models.FileField(storage=key_store, upload_to='myFiles/%Y-%m-%d',
blank=False, null=False)
urls.py
from django.conf.urls import url
from django.contrib import admin
from omicCV import views as omicCV_views
from blog import views as blog_views
urlpatterns = [
url(r'^$', omicCV_views.index),
url(r'^admin', admin.site.urls),
url(r'^AjoutTelechargement$', blog_views.AjoutTelechargement),
]
views.py
from django.views.decorators.csrf import csrf_exempt
from django.http import HttpResponse
from .models import FileUpload
#csrf_exempt
def AjoutTelechargement(request):
if request.method == 'POST':
form = FileUpload(request.POST, request.FILES)
form.save()
return HttpResponse("done!")
I am trying to parse the uploaded pdf files to txt:
def AjoutTelechargement(request):
if request.method == 'POST' and request.FILES['filedir']:
filedir = request.FILES['filedir']
fs = FileSystemStorage(location='myFiles/')
for filename in filedir:
path=filename
if b"pdf" in filename:
print("repère2")
head, tail = os.path.split(path)
var = b"\\"
tail = tail.replace(b".pdf", b".txt")
name = head + var + tail
content = ""
pdf = PyPDF2.PdfFileReader(path, bool('rb'))
for i in range(0, pdf.getNumPages()):
content += pdf.getPage(i).extractText()
print(strftime("%H:%M:%S"), " pdf -> txt ")
with (name, 'a') as f:
text_file_doc = {"file_name": "test_file_name.txt",
"contents": f.write(content.encode('ascii', 'replace').decode('UTF-8'))}
fs.save(filedir.name, text_file_doc)
return HttpResponse("done!")
return HttpResponse("undone")
But got this error in this line: pdf = PyPDF2.PdfFileReader(path, bool('rb'))
Exception Value:
'bytes' object has no attribute 'seek'
Exception Location: C:\Users\RAHMA\omicroneCV\lib\site-packages\PyPDF2\pdf.py in read, line 1689