Properties usadas em buscas nos Models

46 views
Skip to first unread message

Rober Guerra

unread,
Jan 26, 2012, 6:49:07 AM1/26/12
to django...@googlegroups.com
Buenas Djangonautas.

Duvida referente a Properties e Models:

De acordo com o que pude entender sobre o conceito de properties, são uma forma mais elegante e prática usada para substituir getters e setters. Ótimo até ai sempre usei properties.
Mas o real propósito de seu uso seria manter públicos os atributos da classe, no caso em que usamos o propertie, alterando assim somente o nome do atributo e usando o seu nome original na property criada.

Exemplo:
# Model normal, sem necessidade de properties
class Carro(models.Model):
    modelo = models.CharField(max_length=100)
    rodas = model.IntegerField(default=4)
    passageiros = model.IntegerField(default=0)
    
# a partir de um dado momento tive necessidade de ter um get e um set para algum atributo, então criei o propertie
class Carro(models.Model):
    modelo = models.CharField(max_length=100)
    rodas = model.IntegerField(default=4)
    _passageiros = model.IntegerField(default=0, db_column='passageiros')

    def _get_passageiros(self)
        return self._passageiros = p

    def _set_passageiros(self, p)
        self._passateiros  = p

    passageiros = property(_get_passageiros, _set_passageiros)

Neste ultimo caso, como eu ja tenho outros casos de uso onde uso o filtro passageiros ( ex: Carro.objetcs.filter(passageiros=5) ) então optei por alterar o nome do atributo e deixar a property com o nome original. Nos casos comuns onde apenas leio a propertie passageiros funciona normalmente, mas o django não deixa usar ela em um nenhum filter.
Como poderia solucionar isto sem necessidade de alterar os nomes do atributo e da property?

Elyézer Mendes Rezende

unread,
Jan 26, 2012, 6:55:54 AM1/26/12
to django...@googlegroups.com
Um dica, normalmente os getters e setter são usado quando há a
necessidade de algum processamento extra na hora de recuperar ou setar
um atributo.

Da forma como você exemplificou, o simples fato de deixar os
passageiros sem getter e setter oferecerá o mesmo comportamento, ou
seja, na minha opinião, escrever getter e setter como no seu exemplo é
simplesmente reinventar a roda.

Quanto a não permitir usar em filter, eu não cheguei a utilizar, então
não posso dar alguma opinião sobre o assunto.

Até mais

2012/1/26 Rober Guerra <roberz...@gmail.com>:

> --
> Django Brasil em Google Groups
> <http://groups.google.com.br/group/django-brasil>
> Associe-se à Python Brasil e suporte nossa comunidade!
> <http://associacao.python.org.br/>

--
Elyézer Mendes Rezende
http://elyezer.com

Henrique Bastos

unread,
Jan 26, 2012, 6:59:20 AM1/26/12
to django...@googlegroups.com, django...@googlegroups.com
Nesse exemplo usado u não usaria property, mas diretamente o model field "passageiros".

Em um model Django, vc usa property para criar um "model field computado/virtual".

Suponha que tenhamos um model Pessoa com um model field nomecompleto que armazenaria "José das Couves". Você poderia ter uma property "primeironome" que retornaria apenas "José":

class Pessoa(models.Model):
    nomecompleto = models.CharField(max_lenght=100)

    @property
    def primeironome(self):
        return self.nomecompleto.split()[0]

Rober Guerra

unread,
Jan 26, 2012, 7:43:37 AM1/26/12
to django...@googlegroups.com
No caso eu não coloquei nenhum processamento dentro dos getters/setters, pois era só exemplo, mas eles teriam algum processamento a mais sim.
Henrique o meu problema é justamente não mudar o nome do atributo nem do property (pois estou filtrando por este atributo em diversos outros casos de uso e seria inviável alterar a chamada do 'passageiros' emtodos os .filter() ), possibilitando usar o property nos .filter() do model também, neste caso eu mudei o nome do atributo passageiros para '_passageiros' (para ser um atributo privado) e criei um property 'passageiros', que deverá conter algum processamento, para ser usado no lugar do atributo diretamente.
Talvez não tenha me explicado bem... enfim acho que é isso.
--
Att.
Rober Guerra, desenvolvedor web



Gileno Alves

unread,
Jan 26, 2012, 8:21:43 AM1/26/12
to django...@googlegroups.com
Olá Rober,
em python o conceito de privado é apenas convencional, na prática você pode chamar o atributo _passageiros fora do escopo da classe.
Não sei se entendi bem mas você quer utilizar uma property no filter, bem isso não é possível pelo simples fato dessa property não está no banco de dados, como o Henrique falou é algo apenas "computado/virtual" e o filter nada mais é que uma forma de abstrair o select de um banco de dados relacional. O Django quando pegar o seu "filter" ele irá verificar que não existe um campo "passageiros" do tipo:
"django.db.models.fields.Field"
A mensagem de erro será dizendo que não existe o campo "passageiros" e lhe dirá quais os campos possíveis para realizar o filter.

Bem não sei se entendi bem sua dúvida mais é isso ai

2012/1/26 Rober Guerra <roberz...@gmail.com>



--
Gileno Filho, Web Developer

Reply all
Reply to author
Forward
0 new messages