Django - Modelos

Un modelo es una clase que representa una tabla o colección en nuestra base de datos, y donde cada atributo de la clase es un campo de la tabla o colección. Los modelos se definen en la aplicación / modelos.py (en nuestro ejemplo: myapp / modelos.py)

Creando un modelo

A continuación se muestra un modelo de Dreamreal creado como ejemplo:

from django.db import models

class Dreamreal(models.Model):

   website = models.CharField(max_length = 50)
   mail = models.CharField(max_length = 50)
   name = models.CharField(max_length = 50)
   phonenumber = models.IntegerField()

   class Meta:
      db_table = "dreamreal"

Cada modelo hereda de django.db.models.Model.

Nuestra clase tiene 4 atributos (3 CharField y 1 Integer), esos serán los campos de la tabla.

La clase Meta con el atributo db_table nos permite definir el nombre real de la tabla o colección. Django nombra la tabla o colección automáticamente: myapp_modelName. Esta clase te permitirá forzar el nombre de la tabla a tu gusto.

Hay más tipos de campos en django.db.models, puede obtener más información sobre ellos en https://docs.djangoproject.com/en/1.5/ref/models/fields/#field-types

Después de crear su modelo, necesitará Django para generar la base de datos real:

$python manage.py syncdb

Manipulación de datos (CRUD)

Creemos una vista "crudops" para ver cómo podemos hacer operaciones CRUD en modelos. Nuestro myapp / views.py se verá así:

myapp/views.py

from myapp.models import Dreamreal
from django.http import HttpResponse

def crudops(request):
   #Creating an entry
   
   dreamreal = Dreamreal(
      website = "www.polo.com", mail = "[email protected]", 
      name = "sorex", phonenumber = "002376970"
   )
   
   dreamreal.save()
   
   #Read ALL entries
   objects = Dreamreal.objects.all()
   res ='Printing all Dreamreal entries in the DB : <br>'
   
   for elt in objects:
      res += elt.name+"<br>"
   
   #Read a specific entry:
   sorex = Dreamreal.objects.get(name = "sorex")
   res += 'Printing One entry <br>'
   res += sorex.name
   
   #Delete an entry
   res += '<br> Deleting an entry <br>'
   sorex.delete()
   
   #Update
   dreamreal = Dreamreal(
      website = "www.polo.com", mail = "[email protected]", 
      name = "sorex", phonenumber = "002376970"
   )
   
   dreamreal.save()
   res += 'Updating entry<br>'
   
   dreamreal = Dreamreal.objects.get(name = 'sorex')
   dreamreal.name = 'thierry'
   dreamreal.save()
   
   return HttpResponse(res)

Otra manipulación de datos

Exploremos otras manipulaciones que podemos hacer en modelos. Tenga en cuenta que las operaciones CRUD se realizaron en instancias de nuestro modelo, ahora trabajaremos directamente con la clase que representa nuestro modelo.

Creemos una vista de 'manipulación de datos' en myapp/views.py

from myapp.models import Dreamreal
from django.http import HttpResponse

def datamanipulation(request):
   res = ''
   
   #Filtering data:
   qs = Dreamreal.objects.filter(name = "paul")
   res += "Found : %s results<br>"%len(qs)
   
   #Ordering results
   qs = Dreamreal.objects.order_by("name")
   
   for elt in qs:
      res += elt.name + '<br>'
   
   return HttpResponse(res)

Vinculación de modelos

Django ORM ofrece 3 formas de vincular modelos:

Uno de los primeros casos que veremos aquí es el de las relaciones de uno a muchos. Como puede ver en el ejemplo anterior, la empresa Dreamreal puede tener varios sitios web en línea. La definición de esa relación se realiza mediante el uso de django.db.models.ForeignKey -

myapp/models.py

from django.db import models

class Dreamreal(models.Model):
   website = models.CharField(max_length = 50)
   mail = models.CharField(max_length = 50)
   name = models.CharField(max_length = 50)
   phonenumber = models.IntegerField()
   online = models.ForeignKey('Online', default = 1)
   
   class Meta:
      db_table = "dreamreal"

class Online(models.Model):
      domain = models.CharField(max_length = 30)
   
   class Meta:
      db_table = "online"

Como puede ver en nuestro myapp / models.py actualizado, agregamos el modelo en línea y lo vinculamos a nuestro modelo Dreamreal.

Veamos cómo funciona todo esto a través de manage.py shell -

Primero, creemos algunas empresas (entradas de Dreamreal) para probarlas en nuestro shell de Django:

$python manage.py shell

>>> from myapp.models import Dreamreal, Online
>>> dr1 = Dreamreal()
>>> dr1.website = 'company1.com'
>>> dr1.name = 'company1'
>>> dr1.mail = '[email protected]'
>>> dr1.phonenumber = '12345'
>>> dr1.save()
>>> dr2 = Dreamreal()
>>> dr1.website = 'company2.com'
>>> dr2.website = 'company2.com'
>>> dr2.name = 'company2'
>>> dr2.mail = '[email protected]'
>>> dr2.phonenumber = '56789'
>>> dr2.save()

Ahora algunos dominios alojados -

>>> on1 = Online()
>>> on1.company = dr1
>>> on1.domain = "site1.com"
>>> on2 = Online()
>>> on2.company = dr1
>>> on2.domain = "site2.com"
>>> on3 = Online()
>>> on3.domain = "site3.com"
>>> dr2 = Dreamreal.objects.all()[2]
>>> on3.company = dr2
>>> on1.save()
>>> on2.save()
>>> on3.save()

Acceder al atributo de la empresa de alojamiento (entrada Dreamreal) desde un dominio en línea es simple:

>>> on1.company.name

Y si queremos conocer todo el dominio online alojado por una Empresa en Dreamreal usaremos el código -

>>> dr1.online_set.all()

Para obtener un QuerySet, tenga en cuenta que todos los métodos de manipulación que hemos visto antes (filter, all, exclude, order_by ....)

También puede acceder a los atributos del modelo vinculado para las operaciones de filtrado, digamos que desea obtener todos los dominios en línea donde el nombre de Dreamreal contiene 'empresa' -

>>> Online.objects.filter(company__name__contains = 'company'

Note- Ese tipo de consulta solo es compatible con SQL DB. No funcionará para bases de datos no relacionales donde las uniones no existen y hay dos '_'.

Pero esa no es la única forma de vincular modelos, también tienes OneToOneField, un vínculo que garantiza que la relación entre dos objetos es única. Si usamos OneToOneField en nuestro ejemplo anterior, eso significaría que para cada entrada de Dreamreal solo es posible una entrada en línea y al revés.

Y el último, la relación ManyToManyField for (nn) entre tablas. Tenga en cuenta que son relevantes para bases de datos basadas en SQL.