Pereiti prie turinio

Rekomenduojami pranešimai

Sveiki, neseniai pradėjau mokytis Python + Django, tad iškilo ne vienas klausimas.

 

1. Templates

 

Templeitas templeite.

 

Tarkim, turiu failą default.html, kurio turinys toks:

 

<html>

<head>[i]Stiliai, antraštė[/i]</head>

<body>

{{ block content }}

{{ endblock }}

</body>

</html>

 

bei main.html

 


<div class="juosta">{{ h1 }}</div>

 

Taigi, jei rašau

 

 

return render_to_response('default.html', {'content' : 'Labas'})

 

tada viskas gerai, tačiau kaip man padaryti, kad h1 atributas būtų nusiųstas į main.html, o iš ten content pavidalu į default.html?

 

2. Duomenų bazės struktūra

 

Pasidomėjau duombazių valdymu, radau kelis pavyzdžius, pasipraktikavau su duomenų įvedimu, išvedimu, tvarkymu, tačiau vis dar tiksliai nesuvokiu, kaip tai veikia, kokia duomenų struktūra (naudoju PostgreSQL). Anksčiau naudojausi MySQL ir PHP, tad per MySQL Workbench ar phpmyadmin viskas puikiai matydavosi. Čia, deja, viskas nemažai skiriasi, visi modeliai ir t.t. Na, gal priprasiu, tačiau gal galit kas vizualiai paaiškinti, kaip tai veikia?

 

3. <div> tag'ų keitimasis tarpusavyje

 

Pvz. egzistuoja stilių klasės k1 ir k2.

 

Php daryčiau taip:

 


$k = 'k1';

while (sąlyga) {

   echo '<div class="'.$k.'">Eilutė</div>';

   $k = $k == 'k1' ? 'k2' : 'k1';

}

 

Kaip šitai įgyvendinti su Django?

 

 

 

 

Laukiu atsakymų. ^_^

 

Nuoroda į pranešimą
Dalintis kituose puslapiuose

http://docs.djangoproject.com/en/1.3/ref/templates/builtins/

 

Susirandi „extends“(dėl persiuntimo), „cycle“(čia dėl kelių klasių).

 

Dėl to, kad persiųstų į kitą template: http://docs.djangoproject.com/en/1.3/topics/templates/#template-inheritance

 

Dėl modelių - Django tarpininkauja tarp tavęs ir tavo duomenų bazės. Ji už tave sukuria visas *SQL užklausas ir tu gali ramiai sedėdamas rašyti tik tiek, kad Django suvoktų kiek ir kaip, ko tau reik.

Redagavo nagisa
Nuoroda į pranešimą
Dalintis kituose puslapiuose

Pamačius tokį temos pavadinimą akimirksniu ištinka geekgasm'as!! :)

 

1. Su {{ tokiais tagais }} apgaubiami tik variable. Blockai ir kiti template tagai eina su {% tokiais %} :)

 

default.html viskas gerai, tik pataisyk tagus, o main.html turi atrodyti taip:

{% extends "default.html" %}
{% block content %}
<div class="juosta">{{ h1 }}</div>
{% endblock %}

 

Tik nesupratau, kodėl main.html rašai {{ h1 }}, tuo tarpu view'e variable vadinasi - content :)

 

Ai beje, renderinti turi tada main.html :)

 

 

2. Ko būtent nesupratai? Jei nesi daręs savo modelių, pabandyk daryti ir tada per tą patį PHPMyAdmin analogišką tools'ą, skirtą Postgres pasižiūrėk. Django pats iš modelių sukuria DB struktūrą. Jei gali, patikslink klausimą, ne iki galo supratau :)

 

 

3. Django dokumentacijoj pateiktas puikus pavyzdys su tagu „cycle“

 

Tavo atveju būtų:

{% for o in objektai %}
   <div class="{% cycle 'k1' 'k2' %}">
       ...
   </div>
{% endfor %}

 

Django defaultu while tago lyg ir neturi :)

Redagavo Silke
Nuoroda į pranešimą
Dalintis kituose puslapiuose

Dėkui už atsakymus, supratau, ką reikėjo.

 

Tiesa, pirmą projektą, kaip ir su PHP, žadu daryti naršyklinį žaidimą. Ar tinkamas projektas pagal Django galimybes?:)

Nematau kodėl negalėtų būti netinkamas. Django tikrai gali tiek ir dar daugiau :)

Nuoroda į pranešimą
Dalintis kituose puslapiuose

Įdomu tikrai kurti. Dar nelabai suvokiu, kaip, bet viskas, ką padarau, veikia. Labai patinka, kad nebereikia formų tikrinti su isset visais, užtenka isvalid (ar neužtenka?). Dar nelabai pripratau prie templeitų, bet jau suplanavęs esu, kur ateityje jie man pravers.:)

Nuoroda į pranešimą
Dalintis kituose puslapiuose

Įdomu tikrai kurti. Dar nelabai suvokiu, kaip, bet viskas, ką padarau, veikia. Labai patinka, kad nebereikia formų tikrinti su isset visais, užtenka isvalid (ar neužtenka?). Dar nelabai pripratau prie templeitų, bet jau suplanavęs esu, kur ateityje jie man pravers.:)

 

Iš tikrųjų Frameworkas padeda susidaryti griežtesnę struktūrą, kai be frameworko gali daryti bet ką, bet kaip, kad ir nenaudoti template'ų, kaip pats minėjai. Kai priprasi, pats pamatysi, kad viskas daug švariau :) Minėtas formų validavimas taip pat - iš esmės validate'ina jau patys laukeliai, taip pat gali aprašyti savų validavimo sąlygų :)

Nuoroda į pranešimą
Dalintis kituose puslapiuose

Tada dar noriu paklaust.

 

Tarkim yra formos laukelis

user = form.CharField(max_length=15)

 

Taigi, jei bus įvestas per ilgas vart.v. arba bus neįvestas išvis, tada isvalid išmes False. O tada jau rankiniu būdu tikrint, kas blogai konkrečiai? Tarkim if len(request.GET) > 15...

 

Ir dar įdomu. Php yra preg_match, kaip tai panaudoti formose čia?:)

 

Ir spėju teks regexp man išmokti, nors ir savaitę truktų.;)

Nuoroda į pranešimą
Dalintis kituose puslapiuose

Tada dar noriu paklaust.

 

Tarkim yra formos laukelis

user = form.CharField(max_length=15)

 

Taigi, jei bus įvestas per ilgas vart.v. arba bus neįvestas išvis, tada isvalid išmes False. O tada jau rankiniu būdu tikrint, kas blogai konkrečiai? Tarkim if len(request.GET) > 15...

 

Ir dar įdomu. Php yra preg_match, kaip tai panaudoti formose čia?:)

 

Ir spėju teks regexp man išmokti, nors ir savaitę truktų.;)

preg_match tai paprasčiausi regexai? Pythone tam yra re biblioteka. :) Jei būtent validatinant, yra RegexValidator.

 

Prie klaidų berods galima prieiti per form.errors po to, kai forma yra validuojama :)

Nuoroda į pranešimą
Dalintis kituose puslapiuose

Na ir paskutiniai keli klausimai (nes tikrai per daug klausinėju) :D

 

1. Niekaip nepriverčiu POST metodo veikti.

 

Formoje įrašau:

 

{% csrf_token %}

 

views.py:

 

from django.template import RequestContext

 

išvedu:

 

c = RequestContext(request, {

'h1' : 'Registracija',

'auth':False,

'klaida':'Slaptažodžiai nesutampa',

'link' : '<a href="/register/">Bandyti vėl...</a>'

})

return render_to_response('auth.html', c)

 

 

 

 

arba

 

 

return render_to_response('auth.html', {

'h1' : 'Registracija',

'auth':False,

'klaida':'Slaptažodžiai nesutampa',

'link' : '<a href="/register/">Bandyti vėl...</a>'

},

context_instance=RequestContext(request))

 

 

gaunu:

 

Forbidden (403)

 

CSRF verification failed. Request aborted.

Help

 

Reason given for failure:

CSRF token missing or incorrect.

 

 

ieškojau sprendimo visur, bandžiau įvairiai, tačiau spėju, kad RequestContext naudoju blogai.

 

2. Kas ta Google App Engine?

 

Daug kur ją mini, vieni ją peikia, kiti giria, tačiau konkretaus atsakymo, kuo ji padeda nerandu.:)

 

3. Vėl dėl formų.

 

user = form.CharField(parametrai)

 

Kokį parametrą įrašyti, kad palygintų du kintamuosius, pvz user == user2.

 

 

 

 

Iš anksto ačiū už atsakymus. Rep+! ^_^

Redagavo aemdy
Nuoroda į pranešimą
Dalintis kituose puslapiuose

1. ar {% csrf_token %} būna tarp <form> tagų? Ar settings.py į MIDDLEWARE_CLASSES įdėjai django.middleware.csrf.CsrfViewMiddleware? RequestContext naudoji lyg ir gerai.

 

2. Google App Engine tai toks lyg ir cloud „hostingas“/frameworkas, palaikantis Python ir Java aplikacijas. Tiesa, jame galima paleisti ir Django, bet man nepavyko ir greit praradau kantrybę... :D

 

3. Na čia manau reiktų ne rašyti ne į laukelį, o tiesiog pasidaryti validatorių formoje:

 

class ExampleForm(forms.Form):
   # ...
   def clean_user(self):
       u1, u2 = self.cleaned_data['user'], self.cleaned_data['user2']
       if u1 != u2:
           raise forms.ValidationError('User ir user2 nesutampa')
       return u1

 

Nebandžiau, bet turėtų būti kažkas tokio :)

Redagavo Silke
Nuoroda į pranešimą
Dalintis kituose puslapiuose

1. ar {% csrf_token %} būna tarp <form> tagų? Ar settings.py į MIDDLEWARE_CLASSES įdėjai django.middleware.csrf.CsrfViewMiddleware? RequestContext naudoji lyg ir gerai.

 

MIDDLEWARE_CLASSES = (
   'django.middleware.common.CommonMiddleware',
   'django.contrib.sessions.middleware.SessionMiddleware',
   'django.middleware.csrf.CsrfViewMiddleware',
   'django.contrib.auth.middleware.AuthenticationMiddleware',
   'django.contrib.messages.middleware.MessageMiddleware',
)

<form action="/register/do" method="post">{% csrf_token %}

return render_to_response('auth.html', {
               'h1' : 'Registracija',
               'auth':False,
               'klaida':'Slaptažodžiai nesutampa',
               'link' : '<a href="/register/">Bandyti vėl...</a>'
               },
               context_instance=RequestContext(request))


CSRF verification failed. Request aborted.

 

Viskas lyg ir taip. :unsure:

 

Serverio cmd rašo "csrf_token was used in a template, but the context didn't provide the value...

 

 

 

Redagavo aemdy
Nuoroda į pranešimą
Dalintis kituose puslapiuose

 

Viskas lyg ir taip. :unsure:

 

Serverio cmd rašo "csrf_token was used in a template, but the context didn't provide the value...

Na čia gal ir negerai darai, pirmiausiai sukurk RequestContext:

 

data = {'var' : 'blah'}
cont = RequestContext(request,data)
render_to_response('templ.html',cont)

 

Nors kažką panašaus bandei, bet pabandyk ir taip.

Nuoroda į pranešimą
Dalintis kituose puslapiuose

Po truputį bandžiau išsiaiškinti, kur viskas nutrūksta. Pastebėjau, kad nėra vykdoma nė viena funkcijos eilutė.

 

Kaip urls.py turėtų atrodyti?

 

Yra: url(r'^register/do$', RegProcess),

 

Ar darai:

from tavo_aplikacija.views import RegProcess

?

Jei taip, tai lyg viskas ir gerai būtų...

Iš mano vieno projekto pavyzdys:

from hack.views import *

urlpatterns = patterns('',
   ('^$',index),
   ('^level1/$', level1),
## <...>
)

Nuoroda į pranešimą
Dalintis kituose puslapiuose

Ar darai:

from tavo_aplikacija.views import RegProcess

?

Jei taip, tai lyg viskas ir gerai būtų...

Iš mano vieno projekto pavyzdys:

from hack.views import *

urlpatterns = patterns('',
   ('^,index),
   ('^level1/, level1),
## <...>
)

Yra from waypi.views import *

 

Gal čia kas ne taip...

 

def RegProcess(request):

form = RegistrationForm(request.POST)

if form.is_valid():

 

 

...

 

EDIT: Susitvarkiau.;)

 

 

Trūko 'django.middleware.csrf.CsrfResponseMiddleware',

 

 

Redagavo aemdy
Nuoroda į pranešimą
Dalintis kituose puslapiuose

Trūko 'django.middleware.csrf.CsrfResponseMiddleware',

 

Turėk omeny, kad:

DEPRECATED Middleware that post-processes a response to add a csrfmiddlewaretoken.

 

This exists for backwards compatibility and as an interim measure until applications are converted to using use the csrf_token template tag instead. It will be removed in Django 1.4.

Turbūt yra kažkoks kitas būdas tam, nežinau, man ir be ResponseMiddleware veikia :)

Nuoroda į pranešimą
Dalintis kituose puslapiuose

O tai ką daryti, jei kitaip neveikia?

 

Vienos bėdos, su PHP buvo tikrai paprasčiau.

 

Dabar nepagaunu, kaip veikia formų tikrinimas.

 

pvz.

 

from django.core.validators import *

username = forms.CharField(
       max_length=15,
       error_messages={'required': 'Neįvestas vartotojo vardas!'},
       validator_list=[validators.isAlphaNumeric]
   )

O tada gaunu

name 'validators' is not defined

 

Google niekuo padėti negali.

Redagavo aemdy
Nuoroda į pranešimą
Dalintis kituose puslapiuose

O tai ką daryti, jei kitaip neveikia?

 

Vienos bėdos, su PHP buvo tikrai paprasčiau.

 

Dabar nepagaunu, kaip veikia formų tikrinimas.

 

pvz.

 

from django.core.validators import *

username = forms.CharField(
       max_length=15,
       error_messages={'required': 'Neįvestas vartotojo vardas!'},
       validator_list=[validators.isAlphaNumeric]
   )

O tada gaunu

name 'validators' is not defined

 

Google niekuo padėti negali.

PHP nėra frameworkas.

Čia ne su Django suklydai, o su pačiu python:

# jei importuoji modulius tokiu stilium:
from modulis import a, b, c
# ar 
from modulis import *
# tada viską gali pasiekti be jokių modulio prefiksų
a()
b()
c()

# jie reikalingi tik tada, jei darai:
import modulis
# tada:
modulis.a()
modulis.b()

tavo atveju reikia pakeisti iš validators.isAlphaNumeric į tiesiog isAlphaNumeric. Esi mokęsis python prieš Django?

Nuoroda į pranešimą
Dalintis kituose puslapiuose

Pagrindus išmokau, bet per giliai nekapsčiau. Su laiku išsiaiškinsiu, svarbu, kad tik neatsibostų, nes atsibosta tada, kai lygioj vietoje niekas nesigauna, kaip norėtųsi. Einu djangobook darsyk perverst, gal kokius naudingus dalykus praverčiau.;)

 

EDIT: Kadangi tikslas yra žaidimas, o jam reikės ne vienos lentelės (modelio?) duombazėj. Šiuos, kaip suprantu, galima sukurti tik pakūrus app. Norėčiau tada sužinot kai ką.

 

Konkretus pavyzdys.

Kad ir paprastas RPG žaidimas - žaidėjai, inventorius, įgūdžiai, užduotys...

Tai kiekvienai kategorijai kurti po atskirą app ar viską viename? Beje, jei atskirai, tai kaip paskui surišti įgūdžių lentą iš vieno app su žaidėjų lenta iš kito?

 

Beje, kaip reikia atlikti count(*) su kriterijais. Pavyzdžiui, norint gauti žaidėjų online skaičių daryčiau

SELECT COUNT(*) FROM users WHERE online_ts > time()

 

Dabar bandau

Players.objects.filter(online_ts>time()).count()

, bet...

global name 'online_ts' is not defined

 

Žinoma, manau pavyktų su

len(Players.objects.get(online_ts>time())), bet man atrodo yra efektyvesnis būdas...

 

 

Redagavo aemdy
Nuoroda į pranešimą
Dalintis kituose puslapiuose

Konkretus pavyzdys.

Kad ir paprastas RPG žaidimas - žaidėjai, inventorius, įgūdžiai, užduotys...

Tai kiekvienai kategorijai kurti po atskirą app ar viską viename? Beje, jei atskirai, tai kaip paskui surišti įgūdžių lentą iš vieno app su žaidėjų lenta iš kito?

 

Beje, kaip reikia atlikti count(*) su kriterijais. Pavyzdžiui, norint gauti žaidėjų online skaičių daryčiau

SELECT COUNT(*) FROM users WHERE online_ts > time()

 

Dabar bandau

Players.objects.filter(online_ts>time()).count()

, bet...

global name 'online_ts' is not defined

 

Žinoma, manau pavyktų su

len(Players.objects.get(online_ts>time()))

, bet man atrodo yra efektyvesnis būdas...

 

Atskiros app kiekvienam modeliui TIKRAI nereikia. Jei visi jie skirti tam žaidimui, tai gali kurt vienoje aplikacijoje.

 

Šiek tiek negerai darai tą query, turėtų būti:

 

from datetime import datetime # nežinau ar time() čia veiks, bet jei online_ts yra DateTimeField, tada jis bus grąžinamas kaip python datetime objektas, o ne kaip paprastas float numeris, todėl reikia ir lyginti su datetime
import time

Players.object.filter(online_ts__gt=datetime.now()) # tiesa, nemanau, kad tai suveiks, juk dabartinis laikas
# visad bus didesnis, už userio paskutinio apsilankymo laiką?
# Gal geriau būtų ieškoti userių, kurie buvo aktyvūs per paskutinę 1 min.?
# Labai lengva susikonstruoti datetime objektą kurio laikas būtų prieš minutę:
da = datetime.fromtimestamp(time.time()-60) 
# fromtimestamp kaip vadinasi, tą ir daro - duoda datetime objektą
# iš timestampo. Gauname time.time(), t.y. dabartinį timestamp, 
# iš jo atimam 60 sekundžių ir tada jau su juo galima lyginti :)

T.y. darant query negalima naudoti tokių standartinių python ženklų kaip > ar <, yra laukelis__lt ir panašūs (lt - lower than, lte - lower than or equal, gt - greater than, gte - greater than or equal)

Paskaityk šį dokumentacijos skyrių, būtent tai ko tau reikia.

 

O dėl modelių ryšių (relationships) su kitų aplikacijų modeliais tai (pavyzdys su User modeliu iš django.contrib.auth aplikacijos):

 

from django.contrib.auth.models import User
# nekreipk dėmesio į necenzūrinį pavadinimą, 
# mano pirmasis projektas django mokymuisi - twitter klonas :D
# iš tikrųjų gerai išsisaugoti ankstesnius kodus, kartais praverčia :)
class Twat(models.Model): 
   author = models.ForeignKey(User,blank=False) # pakankamai paprasta

Pakankamai paprastas ryšys ForeignKey ryšys (tikiuosi skaitei apie ryšius?). Tada prie autoriaus galima prieiti tiesiog taip:

from twat.models import *
tw = Twat.objects.all()[0]
aut = tw.author
print aut.username
#output : silkuze

Iš tikrųjų geras ORM labai palengvina darbą :)

Redagavo Silke
Nuoroda į pranešimą
Dalintis kituose puslapiuose

Na dėl timestamp, tai aš esu pratęs kaskart vartotojui atnaujinimus puslapį jį padidinti x sekundžių.

 

Pvz. vartotojams, kurie buvo aktyvūs paskutines 5min:

 

Nustatau į duombazę ts = time() + 300

 

o paskui traukiu tik tuos, kur ts > time()

P.S. online_ts dariau IntegerField ir ten dedu šią reikšmę:

 

from time import time

 

ts = time()

 

 

Redagavo aemdy
Nuoroda į pranešimą
Dalintis kituose puslapiuose

Prisijunkite prie diskusijos

Jūs galite rašyti dabar, o registruotis vėliau. Jeigu turite paskyrą, prisijunkite dabar, kad rašytumėte iš savo paskyros.

Svečias
Parašykite atsakymą...

×   Įdėta kaip raiškusis tekstas.   Atkurti formatavimą

  Only 75 emoji are allowed.

×   Nuorodos turinys įdėtas automatiškai.   Rodyti kaip įprastą nuorodą

×   Jūsų anksčiau įrašytas turinys buvo atkurtas.   Išvalyti redaktorių

×   You cannot paste images directly. Upload or insert images from URL.

Įkraunama...
  • Dabar naršo   0 narių

    Nei vienas registruotas narys šiuo metu nežiūri šio puslapio.

×
×
  • Pasirinkite naujai kuriamo turinio tipą...