iT邦幫忙

0

Python QuerrySet處理多筆資料陣列出錯?

  • 分享至 

  • xImage

想請教各位,我目前遇到這個 陣列問題 想不出來要怎麼解 @@

我輸入一筆"編號",有相同編號的資料,就存進檔案下載

但只有我輸入兩筆以上不同的"編號",就會報錯,無法輸出存檔

只輸入一筆"編號"篩選資料條件,可以匯出檔案
圖片

輸入兩筆以上的"編號"篩選資料條件,就會報錯

Error

程式碼:
pic

Views:

def down_file(request):
    ssid = CourseData.objects.all()
    if request.method == "POST":    
        sids = request.POST.get("sids").strip()
        if "," in sids:
            dfs = CourseData.objects.filter(sid = "NA")
            sdfs = sids.split(",")
            for n in sdfs:
                sdfses = CourseData.objects.filter(sid = n.strip())
                dfs = dfs | sdfses
        else : 
            dfs = CourseData.objects.filter(sid__in = [sids]).values_list("sid","name","phone","email","sdept")
        response = HttpResponse(content_type = "text/csv")
        response.write(codecs.BOM_UTF8)
        response['Content-Disposition'] = 'attachment; filename = "Report.csv" ' 
        writer = csv.writer(response)
        writer.writerow(["編號","姓名","手機","信箱","單位"])
    #for df in dfs:
        writer.writerows(dfs)
    return response 
看更多先前的討論...收起先前的討論...
froce iT邦大師 1 級 ‧ 2022-05-18 14:31:44 檢舉
1. 你還是沒給到真正該給的資訊,沒人會知道你199行是哪行啊...

2. 根據通靈的結果,大概是 writer.writerows(dfs) 這行出錯,改成 writer.writerows(list(dfs)) 應該可以。
改成 writer.writerows(list(dfs)) ,會出現 'QuerySet' object has no attribute 'user' 錯誤
froce iT邦大師 1 級 ‧ 2022-05-18 15:02:55 檢舉
你得確保dfs都轉換成 values_list,不管是單個或多個。

然後你 sids 應該是用逗號去做分割?
為啥多個的用迴圈,反而單個的用 sid__in 去篩選?

'QuerySet' object has no attribute 'user' 看起來應該是別的錯誤,而且跟你貼出來的無關。

最後建議變數盡量取能清楚看懂的,你這樣別人很難去理解你到底在幹嘛...
(1) sids 應該是用逗號去做分割? 是的,舉例: 001,002,003 ,逗號做字串分割.
(2)反而單個的用 sid__in 去篩選? 我另一個功能"編號篩選",是這麼寫,可以正確執行;但目前是用在下載功能
froce iT邦大師 1 級 ‧ 2022-05-18 15:46:04 檢舉
所以你就是沒搞懂就亂寫嘛...
初學雖然衝實作的心態很重要,但是一步一步搞懂的心態更重要,不是code拼出來能動,但是你不知道他為啥能動,這樣就好。
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 個回答

0
froce
iT邦大師 1 級 ‧ 2022-05-18 15:37:18

我覺得你完全沒搞懂 filter 怎麼用...

  1. filter產生的結果是 QuerySet 物件(也就是查詢結果的組合,你得看成是一個容器,裡面是一個或多個商品),get因為只有一個,所以就直接把查詢結果給你,沒有外面的容器。
  2. filter可以用欄位和操作的組合,用法請查閱官方文件
  3. 根據上面的官方文件和實測, [欄位]__in 這種操作子可以處理 空/一個/多個 欄位等於輸入值的狀況
searchIDs1 = []
searchIDs2 = [1]
searchIDs3 = [1, 3, 5]

# 永遠傳回 <QuerySet []>
result1 = CourseData.objects.filter(id__in=searchIDs1)
# 傳回 id = 1/3/5的 <QuerySet [1]>
result2 = CourseData.objects.filter(id__in=searchIDs2)
# 傳回 id = 1/3/5的 <QuerySet [1, 3, 5]>
result3 = CourseData.objects.filter(id__in=searchIDs3)
  1. 所以你要的東西應該根本就沒必要寫那的多code,而且很多code不知所云...
  2. 更何況別人根本不知道你那個 sid="NA" 是在幹嘛的,非常難給你一針見血的回答。

q

上面的圖片是主管寫的code,丟下來要依照他提的功能需求去改,給完code後就不管,他也沒空討論也不想討論;我就先照著這份code去改成篩選"編號".
再者,這一個多月被要求轉來改用py寫網頁,因本來就不是學py,很多都還不是很熟悉.

但還是謝謝您的熱心建議與指導.

froce iT邦大師 1 級 ‧ 2022-05-18 16:58:13 檢舉

你主管丟code不管你是他的事,不過要我我也是丟文件給你自己看。
如果你已經是有其他語言的經驗了,我真的覺得你已經搞一個月了,不該還在問這種問題,尤其是python本身已經是很容易理解的語言了,debug訊息又特別清楚,Django文件也很清楚的狀況下。

我自己是在什麼都不會的狀況下自學程式語言,除了python以外,go也自學、php、node沒想學但是看到會改。基礎打得好,要學其他語言都很快、基礎打不好,就會遇到像這種一出問題就不知道怎麼去解的狀況。

我是建議你靜下心來,先把
https://docs.djangoproject.com/zh-hans/4.0/intro/
看完,練習一下debug,再繼續後面的工作。

0
海綿寶寶
iT邦大神 1 級 ‧ 2022-05-18 17:25:48

試試看

def search_by_name(request):
    departments = Departmetn.objects.all()
    cdepartments = CDepartment.objects.all()
    if request.method = "POST":
        psid = request.POST.get("sid").strip()
        if "," in psid:
            courses = CourseData.objects.filter(sid="NA")
            sids = psid.split(",")
            for s in sids:
                course = CourseData.objects.filter(sid=s.strip())
                courses = courses | course
            else:
                courses = CourseData.objects.filter(sid=psid).order_by("dept")
        num = len(courses)
        return render(request, "index.html")
return redirect("/")

合則用不合則算

看更多先前的回應...收起先前的回應...
froce iT邦大師 1 級 ‧ 2022-05-19 08:28:24 檢舉

不用這麼麻煩啦,__in就可以處理所有單選多選的狀況了,只要對傳來的post做確認不是None,然後做split(),變成list,傳給filter做篩選就好。

前面多選的部分...

def search_by_name(request):
    departments = Departmetn.objects.all()
    cdepartments = CDepartment.objects.all()
    if request.method = "POST":
        psid = request.POST.get("sid").strip().split()
        defaultCourse = CourseData.objects.filter(sid="NA")
        courses = CourseData.objects.filter(sid__in=psid)
        courses = courses | defaultCourse
        
        num = len(courses)
        return render(request, "index.html")
return redirect("/")

https://ithelp.ithome.com.tw/upload/images/20220519/200017871GVJMhUBBz.png

harutsuki iT邦新手 5 級 ‧ 2022-05-19 17:35:40 檢舉

問一下,為什麼要查詢兩次,而不是用

Q(sid__in=psid) | Q(sid='NA')

又或者

psid.append('NA')
harutsuki iT邦新手 5 級 ‧ 2022-05-19 17:39:07 檢舉

另外一個問題是,頭兩個查詢沒用到、沒輸出為什麼還要使用?

我要發表回答

立即登入回答