From acbca4104041d1ac9f9e446b0536db9b7a5b0c1b Mon Sep 17 00:00:00 2001 From: Priyatham Sai Chand Date: Fri, 15 Jan 2021 14:35:47 +0530 Subject: [PATCH] file upload form --- .vscode/settings.json | 3 ++ auctions/__pycache__/forms.cpython-39.pyc | Bin 0 -> 1596 bytes auctions/__pycache__/models.cpython-39.pyc | Bin 2394 -> 2328 bytes auctions/__pycache__/views.cpython-39.pyc | Bin 5699 -> 4969 bytes auctions/forms.py | 39 ++++++++++++++++++ auctions/models.py | 2 +- .../templates/auctions/create_listing.html | 28 +++---------- auctions/templates/auctions/listing.html | 2 +- auctions/views.py | 38 ++++++----------- commerce/__pycache__/settings.cpython-39.pyc | Bin 2266 -> 2337 bytes commerce/__pycache__/urls.cpython-39.pyc | Bin 963 -> 1138 bytes commerce/s3_storage.py | 5 +++ commerce/settings.py | 4 ++ commerce/urls.py | 7 +++- db.sqlite3 | Bin 253952 -> 253952 bytes media/Screenshot_2021-01-12_121010.png | Bin 0 -> 7313 bytes .../Screenshot_2021-01-12_121010_fohlCLJ.png | Bin 0 -> 7313 bytes 17 files changed, 76 insertions(+), 52 deletions(-) create mode 100644 .vscode/settings.json create mode 100644 auctions/__pycache__/forms.cpython-39.pyc create mode 100644 auctions/forms.py create mode 100644 commerce/s3_storage.py create mode 100644 media/Screenshot_2021-01-12_121010.png create mode 100644 media/Screenshot_2021-01-12_121010_fohlCLJ.png diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..fafb871 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "python.pythonPath": "C:\\ProgramData\\Anaconda3\\python.exe" +} \ No newline at end of file diff --git a/auctions/__pycache__/forms.cpython-39.pyc b/auctions/__pycache__/forms.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ff6697c08420c7518e4d90888f5480174f0e41f4 GIT binary patch literal 1596 zcmZuxPj4JG6u0O9&d#Q3fHnmL0V-9CU{8nxiV$r|AeVrY3ZYTZFc~|u-prq^?QNRX z!X=e@DxaZ6T>6!K<&>|$iT6B{wh?&bXZt<-`Mvl1dGgUHCeVKWnf|)z6Y@7M-fSK$ zzJac`K`_E-MQWN-N=m|-J{ywF>1!zYu;*fHU5uBM`Gq>Gy!GyE3qvTa16BnAUI@B6mq5~9UL za4>JBRx;>q585*&!)_7ZUFf!Mk3_{~)T#V?ZF{2Rpx^M5V7x8!nk$KQKz~2zDVItP zVOc=G(l97&>N60Wq?D1=VKjB0l4Hso=01s1kNdNLdCY%C)9@+rNE$)*feG&kwhNh; z)&q#bxtzg>sbRkcU3~#UlXEhoD@Tx(`xpHKD!!tO-XtrMIV&>5?lR{VnRzpxx!ZsZ z+~VzDP&jMcBf*SYiw5rX)nd-2iLy*ILT8y7fH8ZNR|{@}W5Fw?OmHe#$+huwt)&`! z##6jHmK*5H%Vh~WPEK)rNzEY3iYiws%U+UyKHd51@JA`may`xK(^j4w-dz+L@H@=A zQ5{;eC-XCT9lX5_T_IG2ZqS%6*ZZPOE~C4^q5w(O7%xPfSJ}ME3$DfkOrQavAb~i` z>Xt1koF`fKaFJJ?#RhEek?6)G_d6%Mn5A4p)u@lY;8m4n@;%UX;ug-{N0ETQSZ$mU z^_;}Fy8o~N8Hi1-KwPqcyEBhbkUsK3Q06_Ozy&7_u2_OMEFoB;{zTa8BVf+}bTJ>Y z0n8KbJ|Ddx>6&F)%!a_UYnEN>fO}%%9m#Xekzf}L!ZAZzxM^E40N>X_SA0z6J75Bm z$94WVt9VoDsYFQ3ka1N=F-Pc@$$`$L7EQSYOo2nV10V^DX)6GW0x5RcuJHCt&}yRT zikv&ZPzv02dhU|v?hA6C{Ic%LJM7dC@lT+$-Z-l8r;T z4o>B56bOo0dnA-N0_=P0`gXK2cG-FI25!EIViQCf_9vu;*dlImMt2`W@A-IxCUp7M z>oUHgN(jgnPT@`A1F}U@_)`R07@|Z|1cMngg(k-{{m{{5Dv|)2dW$_dBR?}a zwRk1tEuO^ElKl9*{POt3loU5j##`(uscDI&IVGD9GrKUdae3w@rl(HkX3b&bm|VfS Mg;8;{E}Jeh03r}A)Bpeg delta 202 zcmbOsbW4agk(ZZ?0SJ!sG9;Yd$a{*Bv1#%RMo+sez7*~ho?gZ%{#2GM))b~x<`mvu zrYHd*PcVf!g%2nr1Y`@R@Pk!}qzI%4wlGAArU(TyXbMk`X8Pe>WtUM>Qc!HAuU}qX zu2+~vQkq;659Y?_<(I^#<(KBA=%r_-X)@ko sPf1NnEX^sI9L%h^xt`gDk%c2P$Y=6NmK;W&$!4ru7?n1^X4Pc|0N0Z}mjD0& diff --git a/auctions/__pycache__/views.cpython-39.pyc b/auctions/__pycache__/views.cpython-39.pyc index edfc5910f9df9200dade28d72ab8eb46d87aacf8..04032c73b9ebe76bbe1c48f01d6e886cb9e66e15 100644 GIT binary patch delta 2027 zcmZuyO>7fK6rQp7&-U60v139ABoIiuNl7S;D5@Z&r2Mo{BNfz2zLM_FSpAJ)lZG^;)UNmcBP@h)HW}zMXyZ=9@R~Z-0E} zkBKQan@uzPd0+4w6GM#sPA|Q`B)-h!2wpsxx>XdWNY%3Sd^uk)lnb1Rw8-3H51x$o zjf+81yu-`GVy_rN(Qi|F;Tm&}$RYl)n25}CzPQkYdX!!O&ka4AOI{fMeo`}eaSt8< z27;qSCU{@AydZ?Uyr>^E9y2)1m^_?3HWumYZdkpUBWnnlp5{5;&-)WOo=de zo!*Pm9XdEluWwRBy5A7qS8wA=OroV@l1U`FJ4bSG2>x%c?bd3QSGJw_55<(!tY7z& zo62^zS+9GIu(H?`Upq-qmz|b>S_>UzBLcfR1AFNvg=Fy0tRyEgqx_`2ka@=U$iFkgHk}D)XbC3e zxP8%xuPRsV(HX_}S|N7No1{^?)?D@*l{Md6ugd54C_gJ-*yW3pNQee$L{7;FlnM@y zE!;(sL5gN8R2;WaEudXYvpCGlPWG<><#w_n(!ILt*Wir2o15fw@@a0iLkE?dOizF) zMIl3=Je8@cBB`_j58yo#>jYGbJ(hI?rtbP7Es;my9Dz!TT_#)LEo1U~z_+B=H`DnD z6{{TK)sL<~S6;voe236xD@^cP3HT=DI8We6ZY4H(n?KUF8Ek}lo39umv5%=|5}$0v zRCBE>)4NY&9~0(1V>8iCJhHYKXW`}4Yegb9g>^5vnQSM!%jq@~DUlBKmCPf1oB4bz zd5wi6%?LZ>TV09BVw1_q8~sN+%H@>3ktV#LTDF7G1*-K5=6G3Oz1a+#DxWaZRg#}a z-MA_!BdcCyuKLxm1zxO`gjrIc9FP6^7R{)PH%8o6HT0W}V5S==tXz42PpT7X)YwW+ zHjZsS?I61%{ldpr&R>fxKcH&!g({24uGT!a;facH(N+~S6>U|%DkoG)Qx|izxPfU) zcmRwMr%AQjTwK|ynG>p)MMiAZHYx?f2u!0!Y4KScMH~iCzch4%8!w?GKOcDB89*I4 zh7cu@bHluS{DbKeOPg?<qRJ04%8&D_@}K;Db%pCtpxuKA zj=9TVbV{umcp@$*Wp4bz>FIi((e6V8yGkde_L4C_<7%M3m|70~Xd%LNl<5vHIfrEb z;KPn`ii-RZq8cHfiiarzl}^;v;4HyB0aYTD2vX*-S~YKusy3KF fC~*7re~9-RR-cv6SZVwZqzA1b%d!qyd28TbhH8&g delta 2627 zcmaJ@O>7%Q6rS<^c)k8f8bX^CLV-fTw8Uv?DO4qtP!eb%6%+~>(01dQIGe1!W@eqV z#Zd&US|n7YXyAav0T2f&aYJxK{9HI90YaJs7cL;qT#yjFH=8zTgxJ-7o_X`;&71e@ z-*1XWt;Z@dBxDXLqt~Z0G`A{bhG~C%Xekx3R4!Np+X1(D$Ax==@|T=c1&oi;u;; zk&2`pHKev5Pg-2NCp(EqVfJitR%-u|Zkn``nJDJknMjfaAf1XBPnuziOYNLU=eTIB zZW)|Jh2tp&hrKCq0-9~yO$o0rPeiq9OlX-jIVb)>72#B<& z1)5V^GZE8PD{8|bj_h{0&|VNk?I;ZbU4X@4F^s!#;n|4COlo&2VojcEXEaPxA*;5w zC68yt2nw@9(FB%-CH%cYbs-2EaVTXFTv0>Ty({8o;4*ry%1F^)??@M<@VvlXL=IY$&gj4mC`giM0^ z4>K{0wDOu-4IalqAa(&QgFA3^7s3!g2|kI6deqL995DoDANlNOny1HW$b(C8|GeO@ zcDYQ&UYP4*9LY3lH-ltmUY9z8FGfjM23-+vI0ui=&Qh2*=C-P*tZnp&+Tx6;H>}?A zgDCkB!h;BTfGaui5d3IwO|;x3$*|uE9MS_IPATV7`yX)#WR9y#_VnQcKwTFn9>MAQ zr88xsHsfc;U?me`` zG?+=)*{UVXWsj+E-A7l9j`!mc6$FfHVXR!n5i&xcg^S!+#JIC2z9D_x?k=zPEoC>W_U%i#@r^nR$`S0n3YI%*{mAPA64=aa*>3(}p5!NV=)naUPD9 zSSN|?QSp*GRs3_n7#Yvh4sV4~EM8ErlNEj~OQisd6Jpr&ZD8SVRBO1R);gg>L zKrthXF66{J>h)rE#bz#y$60>ah84=ZVY2L`xgL~5EPFkxXZIXdxa=;wJ@*6qLqbXF z0M#``(Z6gh=X?1zI?z~=mD1dN{sZqr64CS4Ns=P9%qnRio3lPBp8e-;_iu&gIrUIw zWW`v}B)`qLZ0M3qLt$zFl+U`;nM=|{lXDm6(zGKF)oR^NoP=z2DO!kHoJHYiBAPXv zb#PY0s7>0kmdzujwe;I*qw9{^yV1>Lvjm2q%gKD)hcr(T@yX86@fW1UG+Ca zgGmtM*AvKRQrAStdda~}Rc}LL&$8C<#r@dQ|O(gM$E%DX8{Y-P&>2W+Z4Jb^y)Cp zOlVAlRso|=nd~sZQohg6_H3a+)@O(|pa{ziFQcG6*JNN<}PJuCL1 ze)r)a`Azz3w-G0jGhy^V?bkZj2A?b-^xh^_Fp-6!Ch7<;Az;>vSp@Wnk-9;Tb+>zmvz|YW m6++$(Fi1<+-l3Z;FE`+OeO}S?;T`aA^oBgoyTu#!2L1(6pIl}D diff --git a/auctions/forms.py b/auctions/forms.py new file mode 100644 index 0000000..5c754c4 --- /dev/null +++ b/auctions/forms.py @@ -0,0 +1,39 @@ + +from django import forms + +categories = [ + (None,'Select one...'), + ('Fashion','Fashion'), + ('Electronics','Electronics'), + ('Home','Home'), + ('Sports','Sports'), + ('Toys','Toys'), + ('Automobile','Automobile'), + ('Books','Books'), + ('Videogames','Videogames'), + ('Others','Others') +] + +class BidForm(forms.Form): + bid_value = 0.00 + + def __init__(self, bid_value,*args,**kwargs ): + super().__init__(*args,**kwargs) + self.bid_value = bid_value + 1 + self.fields['bid'].widget.attrs['min'] = self.bid_value + + bid = forms.DecimalField(decimal_places=2) + +class CreateForm(forms.Form): + title = forms.CharField( max_length=100, widget=forms.TextInput(attrs={'placeholder': 'title'})) + desc= forms.CharField(max_length=100,widget=forms.TextInput(attrs={'placeholder': 'description'})) + starting_bid= forms.IntegerField(widget=forms.TextInput(attrs={'placeholder': 'Starting bid'})) + category = forms.ChoiceField(choices=categories) + photo = forms.ImageField() + + def __init__(self, *args, **kwargs): + super(CreateForm, self).__init__(*args, **kwargs) + for visible in self.visible_fields(): + visible.field.widget.attrs['class'] = 'form-control' + + diff --git a/auctions/models.py b/auctions/models.py index 9c4019d..3c1d710 100644 --- a/auctions/models.py +++ b/auctions/models.py @@ -20,7 +20,7 @@ class AuctionListing(models.Model): user = models.ForeignKey(User,on_delete = models.CASCADE) price = models.DecimalField(max_digits = 10,decimal_places = 2) desc = models.CharField(max_length = 1000) - picture = models.URLField(default="https://www.riobeauty.co.uk/images/product_image_not_found.gif") + picture = models.ImageField(); category = models.CharField(max_length = 64,choices=category_choices) date_added = models.DateTimeField(auto_now_add=True) closed = models.BooleanField(default=False) diff --git a/auctions/templates/auctions/create_listing.html b/auctions/templates/auctions/create_listing.html index 9001e5a..7730b14 100644 --- a/auctions/templates/auctions/create_listing.html +++ b/auctions/templates/auctions/create_listing.html @@ -2,33 +2,15 @@ {% block body %} +

Create Listing

-
+ {% csrf_token %} -
- -
-
- -
-
- -
-
- -
-
- -
- + + {{ Form.as_p }} +
- {% endblock %} \ No newline at end of file diff --git a/auctions/templates/auctions/listing.html b/auctions/templates/auctions/listing.html index b9953ea..77b02b0 100644 --- a/auctions/templates/auctions/listing.html +++ b/auctions/templates/auctions/listing.html @@ -20,7 +20,7 @@ - +

{{Listing.desc}}

diff --git a/auctions/views.py b/auctions/views.py index 817f0ac..8ddbe45 100644 --- a/auctions/views.py +++ b/auctions/views.py @@ -5,19 +5,11 @@ from django.shortcuts import render from django.urls import reverse from django import forms from .models import User,AuctionListing,Comment,Bids +from .forms import BidForm,CreateForm -categories = ['Fashion','Electronics','Home','Sports','Toys','Automobile','Books','Videogames', 'Other'] -class BidForm(forms.Form): - bid_value = 0.00 - def __init__(self, bid_value,*args,**kwargs ): - super().__init__(*args,**kwargs) - self.bid_value = bid_value + 1 - self.fields['bid'].widget.attrs['min'] = self.bid_value - - bid = forms.DecimalField(decimal_places=2) def watch(request,title): """ @@ -170,27 +162,21 @@ def create(request): """ Used to create a Listing """ - if request.method == "POST": - title = request.POST["title"] - desc = request.POST["desc"] - starting_bid = request.POST["starting_bid"] - photo_url = request.POST["photo"] - - # alternate photo to display - if photo_url == "": - photo_url = "https://upload.wikimedia.org/wikipedia/commons/thumb/1/15/No_image_available_600_x_450.svg/1280px-No_image_available_600_x_450.svg.png" - category_value = request.POST["category"] - listing_obj = AuctionListing(title = title, desc = desc, user = request.user,price = starting_bid, picture = photo_url,category=category_value) - listing_obj.save() - bid_obj = Bids(bid_value = starting_bid, listing = listing_obj, user = request.user) - bid_obj.save() + if request.method == 'POST': + form = CreateForm(request.POST, request.FILES) + if form.is_valid(): + listing_obj = AuctionListing(title = form.cleaned_data["title"], desc =form.cleaned_data["desc"], user = request.user,price = form.cleaned_data["starting_bid"], picture = form.cleaned_data["photo"],category= form.cleaned_data["category"]) + listing_obj.save() + bid_obj = Bids(bid_value = form.cleaned_data["starting_bid"], listing = listing_obj, user = request.user) + bid_obj.save() return render(request,"auctions/index.html",{ "Listings" : AuctionListing.objects.all() }) - else: + + else: return render(request,"auctions/create_listing.html",{ - "categories":categories - }) + "Form": CreateForm() + }) def bid(request, title): """ Used to bid on a listing diff --git a/commerce/__pycache__/settings.cpython-39.pyc b/commerce/__pycache__/settings.cpython-39.pyc index 95a27fa14af528d75915b5eab18d75a6287777ed..4948a2407be4921216827b4cb4b3c3b6e69345d8 100644 GIT binary patch delta 163 zcmca5xKM~Uk(ZZ?0SJTw7!&49%* z8(-uxGIC4~XIj7!#Zg?6UzC`>`74t)i%=E2er{??W}ILl5|Q8*#No&I&1lC^ zd4furvrK4qgv2sWrw%4n&JGorB0NcDUNg~}@N&6=NS#h9%H)XGwY-j-i(T{RIV1&U zS=~x&_P}lZf3p3rv&y#Cx4EOI$`ZMx%39u3q4qJBl5!@L-RYhU&y|1G?OdFWhW$$w ttg+wg4c-CY)ajM|#O;&28=gO5`G^-U=E2r-WHln#gb|EPtzXM_;2)|(VJH9q delta 110 zcmeywahRPqk(ZZ?0SG?b@r#q4$Scd}Fi~4sDU~&aC6y_QEsMRG3CLzmWl3RcW^86k zXNuxTVGm}|0< diff --git a/commerce/s3_storage.py b/commerce/s3_storage.py new file mode 100644 index 0000000..4325cbf --- /dev/null +++ b/commerce/s3_storage.py @@ -0,0 +1,5 @@ +from storages.backends.s3boto3 import S3Boto3Storage + +class MediaStorage(S3Boto3Storage): + location = 'media' + file_overwrite = False \ No newline at end of file diff --git a/commerce/settings.py b/commerce/settings.py index 016409a..7dcbf90 100644 --- a/commerce/settings.py +++ b/commerce/settings.py @@ -38,6 +38,7 @@ INSTALLED_APPS = [ 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', + 'storages', ] MIDDLEWARE = [ @@ -120,3 +121,6 @@ USE_TZ = True # https://docs.djangoproject.com/en/3.0/howto/static-files/ STATIC_URL = '/static/' + +MEDIA_URL = '/media/' +MEDIA_ROOT = os.path.join(BASE_DIR, 'media') diff --git a/commerce/urls.py b/commerce/urls.py index 2f7a9e0..0bdde9d 100644 --- a/commerce/urls.py +++ b/commerce/urls.py @@ -15,8 +15,13 @@ Including another URLconf """ from django.contrib import admin from django.urls import include, path +from django.conf import settings +from django.conf.urls.static import static urlpatterns = [ path("admin/", admin.site.urls), path("", include("auctions.urls")) -] \ No newline at end of file +] + +if settings.DEBUG: # new + urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) \ No newline at end of file diff --git a/db.sqlite3 b/db.sqlite3 index a2180ed7ed7efffdf5bf827c432868ae518f6bd6..c5c6ef9489059f2f3ce58de012657065d56de23a 100644 GIT binary patch delta 1391 zcmbW1Pi)&{7{>F(b{o4%UgyxM3`#t$g`zdC|0ZcF8l|kGYgf8z)hd`+=4MVEmd2Uw zjBb}KgCo+0a)>xoOcNKFRDrVLNg$XsDgl+I4xtsn#-EJ?a48`5#GyE86RnyUh|6os zdh|ZO?|Hx1XRpKA>u_PG+wFPti6N(caO@qxx?4)+R(ij?rBt1y`&vdvx(QeNbV4au z8prWMQpsAXkt~=_NoNexO6HU~H94ouC$nm9*3tw{;6ofA;$?=5#zZ+L3#=fBJTFw2 zckJyzbeZluisEIxZw7T&zv|l;57d>i5ECR;3JVb~T7E`==KdA zB{)p7?XeT5?QX|%J*~q5T+2gOAk;OBq)AN~E#X>fns(f}AU7Z{= zjM%=B;mDz>vAmfNOQw_`IW;=-d`>$#@sct%*`J(NvWKU~#IQc4TC)j<9-bai3l=-+tk@7B;d1RiQ^|FnU2|K35t zk_-NVby$O6;T9~xeYgv&ujh%pVvFymZIJ!uaYj$kTdBXPq8!*r(B7^x%NE>k&SU|UQ0O~6F9bC zib|0%AC_b$#N>_4X~lUqnPZG3vmDo(v7R;=g~=-!gVEEB+Q_B%P|8r%oT=$nve{io z@&eEC9GlPe%=Qjv)s$uExlGFJZAv!x!nqP0%SR&u$5l2?VC}^=yd(@dyuni8VP0`d z-Y;y=?%9aHHZ8)w@&$IVrLi;%@SaVr)RyMKHKDd` L5LvnQ12*zEB;t?* delta 641 zcmZoTz~69ye}WVfG;z@jFGRt5%o7AD5chx4}|&S!Kq zU^e8tGo5__qo)-A7XEeoEBF`j&*7iOKY_oCzlFb!zklj(KKUl}8 z!U)uJYdZS|#$=#G0aW7NKE`8m3dUI#W?A{g`B^0u$(6<_sTRrE>G_r=7Kv2`d8tLI zX48+{W!xHQSXOT3=vHKwSZL^+;$38rT;^Dnlb+(`W8|2X<7JdskmqZfu1&zV&~k- zz|YJ3k(Y<^VRh4=zA`Fnz~;W)A?{&&}Te diff --git a/media/Screenshot_2021-01-12_121010.png b/media/Screenshot_2021-01-12_121010.png new file mode 100644 index 0000000000000000000000000000000000000000..ffe0c71099aad2dd66793414e4b2427d6765b2c5 GIT binary patch literal 7313 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 H