• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

question-closed Python + Django + PANDAS - jak przepuscic plik z formularza przez skrypt pandas.

VPS Starter Arubacloud
0 głosów
470 wizyt
pytanie zadane 28 sierpnia 2020 w Python przez Ventre90 Obywatel (1,170 p.)
zamknięte 3 września 2020 przez Ventre90

Cześć wszystkim,

Pisze aplikacje web która ma przerobić uploadowany plik .xlsx za pomocą skryptu PANDAS.

Chciałbym aby aplikacja działała tak:

  1. Widok „excle_file” – tu user uploaduje plik .xlsx
def excle_upload(request):
    if request.method =='POST':
        # Czy to w tym miejscu powinna
        # być napisana logika która przepuszcza
        # file przez skrypt pandas
        # i wkłada go do formy w miejsce request.FILE 
        # ???

        form = ExcleForm(request.POST, request.FILES)
        if form.is_valid():
            form.save()
            return redirect('excle_list')
    else:
        form = ExcleForm()

2.Skrypt pandas przerabia plik .xlsx do żądanej postaci (czyli logika + skrypt pandas  chyba musi być także w widoku „excle_file” ??? ) Skrypt zaczyna się tak:

    df = pd.read_excel(os.path.join(path,filename)) # tutaj file przslany przez usera
    df.loc[:,"ODOMETER_FW"] = df.loc[:,"ODOMETER_FW"].fillna(0).astype('int')
    df.dropna(inplace = True)
    df.sort_values(by=['VEHICLE_ID_FW','TRANSACTION_DATE_FW','TRANSACTION_TIME_FW'], ascending=[True,False,False],inplace=True)
    df['ODOMETER_FW'] = df['ODOMETER_FW'].apply(lambda x: 0 if x <1000 else x)
    df.set_index(['VEHICLE_ID_FW'], inplace=True)

3. Widok „excle_list” – ma zawierać już przerobione pliki i daje możliwość ich ściągnięcia

def excle_list(request):
    files = Excel.objects.all()
    return render(request, 'odo_correction/excle_list.html', {'files':files})

Obecnie mam napisane funkcjonalności z pkt 1 i 3 no i oczywiście gotowy skrypt pandas. Aplikacja działa tak, że mogę uploadowac i następnie pobierać dokładnie ten sam plik. (cel to jednak pkt 3). Próbuje dostać się do pliku grzebiąc gdzieś w request.FILES ale mam 2 problemy:

- jak zrobić aby klasa: InMemoryUploadedFile – stała się plikiem excel możliwym do użycia jako DataFrame ?

- jak włożyć przerobiony plik z inputa do zaimplementowanej formy „ExcleForm”

Dodatkowo zamieszczę jeszcze w kolejności: model , forme i formularz uploadu html:

#models.py
class Excel(models.Model):
    country = models.CharField(default= "", max_length = 20)
    file = models.FileField(upload_to ='excel')

    def __str__(self):
        return self.file.name
    
    def delete(self, *args, **kwargs):
        self.file.delete()
        super().delete(*args, **kwargs)

# form.py
class ExcleForm(forms.ModelForm):
    class Meta:
        model = Excel
        fields = ('country','file')
{% extends 'odo_correction/base.html' %}
{% load crispy_forms_tags %}

{% block content %}
    <h2> Upload .xlsx ODO file</h2>
    <form method="post" enctype="multipart/form-data">
        {% csrf_token %}
        {{ form|crispy }}
        <button type="submit" class="btn btn-primary">Upload File</button>
    </form>
{% endblock %}

Jeśli ktoś ma jakieś doświadczenie tego typu problemie, to bardzo proszę o pomoc, gdzie szukać informacji i czym się kierować?

Dziękuje i Pozdrawiam!

komentarz zamknięcia: Temat wyjaśniony

1 odpowiedź

+1 głos
odpowiedź 29 sierpnia 2020 przez Nelson89 Dyskutant (7,720 p.)
wybrane 2 września 2020 przez Ventre90
 
Najlepsza

Cześć,

Skrypt pandas przerabia plik .xlsx do żądanej postaci (czyli logika + skrypt pandas  chyba musi być także w widoku „excle_file” ??? )

Generalnie ta działanie powinno znaleźć się w widoku ale nie musisz tego robić bezpośrednio w kodzie danego widoku - możesz to wrzucić do modułu, dzięki temu przy skomplikowanej, rozbudowanej logice nie zaśmiecisz sobie kodu widoku.

 

- jak zrobić aby klasa: InMemoryUploadedFile – stała się plikiem excel możliwym do użycia jako DataFrame ?

Do tego możesz użyć kodu:

import io
import pandas as pd

...

def excle_upload(request):
    if request.method == 'POST':
        file = request.FILES['fileToUpload'].read()
        excel_file = pd.ExcelFile(io.BytesIO(f))

Plik jest wyciągany z requestu.FILES. Następnie po przez użycie funkcji read() transformujesz  plik z klasy django.core.files.uploadedfile.InMemoryUploadedFile do klasy bytes. Na tym etapie masz plik w postaci binarnej - jakbyś otworzył plik z wykorzystaniem wbudowanej funkcji open i trybem rb. Następnie tworzysz obiekt klasy io.BytesIO, który może być otwarty przez pandas.

- jak włożyć przerobiony plik z inputa do zaimplementowanej formy „ExcleForm

form = ExcleForm(request.POST, request.FILES)
        if form.is_valid():
            # edycja pliku
            request.FILES['nazwa'] = ... # a tutaj podmiana
            # ponowne przypisanie danych z requestu do formy 
            form = ExcleForm(request.POST, request.FILES) 
            form.save()

Mógłbyś spróbować edytować ten plik, następnie utworzyć obiekt klasy django.core.files.uploadedfile.InMemoryUploadedFile i przypisać go do request.FILES. Tego nie próbowałem, a tutaj masz kod tej klasy. Druga opcja, po zapisaniu formy - otwórz uploadowany plik w pandas, edytuj i nadpisz oryginalny plik. W bazie danych masz ścieżkę do pliku, a nie sam plik, więc z tym nie powinno być problemu i jest to łatwiejsze niż pierwsze rozwiązanie.

Pozdrawiam,

Nelson

komentarz 30 sierpnia 2020 przez Ventre90 Obywatel (1,170 p.)

Cześć Nelson

Druga opcja, po zapisaniu formy - otwórz uploadowany plik w pandas, edytuj i nadpisz oryginalny plik. W bazie danych masz ścieżkę do pliku, a nie sam plik, więc z tym nie powinno być problemu

Bardzo dziękuje za pomoc i sugestie. Ten drugi sposób, który sugerujesz faktycznie brzmi lepiej. Czy ta operacja może byc zawarta w tym samym widoku pod linią z zapisem formy ? Czyli wywolanie obiektu modelu z bazy po pk i odwolanie sie do jego url i to powinno zadzialac dla pandas ? Nastepnie moglbym ten plik przypisac ponownie do request.FILES['file'] i ponownie zapisac forme ? Czy to mniej wiecej tak ma wygladac ?

komentarz 1 września 2020 przez Nelson89 Dyskutant (7,720 p.)

Możesz to zrobić od razu w tym samym widoku. Po pk możesz wywołać obiekt, a w obiekcie będziesz mieć ścieżkę do pliku, którą możesz przekazać do pandas. W pandas plik zostanie otwarty, edytowany i zapisany. Jako potwierdzenie, że plik został edytowany przez pandas możesz dodać do modelu atrybut (typ boolaen, domyślna wartość False), który określałby fakt, czy plik został edytowany. Po edycji wartość wynosiłaby True.

W punktach mogłoby to wyglądać tak:

  1. Sprawdzenie czy forma jest poprawna (form.is_valid()) - kolejne kroki dla wartości True,
  2. Zapis formy - czyli zapis danych do bazy danych,
  3. Wyszukanie obiektu, z nowo zapisanymi danymi,
  4. Pobranie ścieżki do pliku z obiektu,
  5. Edycja pliku w pandas,
  6. Zapis pliku,
  7. Edycja atrybutu obiektu z False na True,
  8. Zapis obiektu w bazie danych - po przez użycie metody save().

Pozdrawiam,

Nelson

komentarz 2 września 2020 przez Ventre90 Obywatel (1,170 p.)

@Nelson jeszcze raz wielkie dzięki za stworzenie tej listy, która uporządkowała mi wszystko w głowie. Teraz wszystko "działa jak natura chciała" - jak to mawia klasyk. Excel, który pobieram z aplikacji jest już przerobiony.

Zrobiłem nowy widok gdzie plik jest otwierany i nadpisywany przez pandas, a następnie zapisany jest cały model. Skrypt pandas umieściłem w klasie modelu, co pozwala mi tylko wywoływać funkcje w nadmienionym widoku. Tak jest chyba najczytelniej. Na początku nie miałem pojęcia co zrobić a teraz to tylko 5 linijek kodu. Zostało mi teraz podorabiac trochę ikon, sygnałów, czy popupów z progress barami ale to juz mam nadzieje dam rade sam zrobić ;)

Jeszcze raz dzięki i pozdrawiam!

widok:

def excel_correction(request, pk):
    ex = Excel.objects.get(pk=pk)
    df = ex.odo()
    ex.save_excel(df)
    ex.corrected = True
    ex.save()
    return redirect('excel_list')

form:

<form method="post" action="{% url 'excel_correction' f.pk %}">
       {% csrf_token %}
       <button type="submit" class="btn btn-success btn-sm">Correct</button>
 </form>

 

komentarz 2 września 2020 przez Nelson89 Dyskutant (7,720 p.)
Super powodzenia przy dalszej pracy!

pozdrawiam

Nelson

Podobne pytania

0 głosów
0 odpowiedzi 460 wizyt
pytanie zadane 28 marca 2021 w Python przez PIxEL Nowicjusz (180 p.)
0 głosów
1 odpowiedź 1,239 wizyt
pytanie zadane 22 czerwca 2019 w Python przez 001greg001 Bywalec (2,030 p.)
0 głosów
0 odpowiedzi 936 wizyt
pytanie zadane 27 lutego 2019 w Python przez Dawid89 Obywatel (1,120 p.)

92,775 zapytań

141,703 odpowiedzi

320,560 komentarzy

62,109 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...