Me gusta joctee's answer, porque es muy simple.
if hasattr(request.user, 'type1profile'):
# do something
elif hasattr(request.user, 'type2profile'):
# do something else
else:
# do something else
Otros comentaristas han expresado su preocupación de que no puede trabajar con ciertas versiones de Python o Django, pero the Django documentation muestra esta técnica como una de las opciones:
You can also use hasattr to avoid the need for exception catching:
>>> hasattr(p2, 'restaurant')
False
Por supuesto, el La documentación también muestra la técnica de captura de excepción:
p2 doesn’t have an associated restaurant:
>>> from django.core.exceptions import ObjectDoesNotExist
>>> try:
>>> p2.restaurant
>>> except ObjectDoesNotExist:
>>> print("There is no restaurant here.")
There is no restaurant here.
Estoy de acuerdo con Joshua que la captura de la excepción aclara lo que está sucediendo, pero me parece más desordenado. Tal vez este es un compromiso razonable?
>>> print(Restaurant.objects.filter(place=p2).first())
None
Esto es solo consultar el Restaurant
objetos por lugar. Devuelve None
si ese lugar no tiene restaurante.
Aquí hay un fragmento ejecutable para que juegue con las opciones. Si tiene Python, Django y SQLite3 instalados, debería ejecutarse. Lo probé con Python 2.7, Python 3.4, Django 1.9.2 y SQLite3 3.8.2.
# Tested with Django 1.9.2
import sys
import django
from django.apps import apps
from django.apps.config import AppConfig
from django.conf import settings
from django.core.exceptions import ObjectDoesNotExist
from django.db import connections, models, DEFAULT_DB_ALIAS
from django.db.models.base import ModelBase
NAME = 'udjango'
def main():
setup()
class Place(models.Model):
name = models.CharField(max_length=50)
address = models.CharField(max_length=80)
def __str__(self): # __unicode__ on Python 2
return "%s the place" % self.name
class Restaurant(models.Model):
place = models.OneToOneField(Place, primary_key=True)
serves_hot_dogs = models.BooleanField(default=False)
serves_pizza = models.BooleanField(default=False)
def __str__(self): # __unicode__ on Python 2
return "%s the restaurant" % self.place.name
class Waiter(models.Model):
restaurant = models.ForeignKey(Restaurant)
name = models.CharField(max_length=50)
def __str__(self): # __unicode__ on Python 2
return "%s the waiter at %s" % (self.name, self.restaurant)
syncdb(Place)
syncdb(Restaurant)
syncdb(Waiter)
p1 = Place(name='Demon Dogs', address='944 W. Fullerton')
p1.save()
p2 = Place(name='Ace Hardware', address='1013 N. Ashland')
p2.save()
r = Restaurant(place=p1, serves_hot_dogs=True, serves_pizza=False)
r.save()
print(r.place)
print(p1.restaurant)
# Option 1: try/except
try:
print(p2.restaurant)
except ObjectDoesNotExist:
print("There is no restaurant here.")
# Option 2: getattr and hasattr
print(getattr(p2, 'restaurant', 'There is no restaurant attribute.'))
if hasattr(p2, 'restaurant'):
print('Restaurant found by hasattr().')
else:
print('Restaurant not found by hasattr().')
# Option 3: a query
print(Restaurant.objects.filter(place=p2).first())
def setup():
DB_FILE = NAME + '.db'
with open(DB_FILE, 'w'):
pass # wipe the database
settings.configure(
DEBUG=True,
DATABASES={
DEFAULT_DB_ALIAS: {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': DB_FILE}},
LOGGING={'version': 1,
'disable_existing_loggers': False,
'formatters': {
'debug': {
'format': '%(asctime)s[%(levelname)s]'
'%(name)s.%(funcName)s(): %(message)s',
'datefmt': '%Y-%m-%d %H:%M:%S'}},
'handlers': {
'console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler',
'formatter': 'debug'}},
'root': {
'handlers': ['console'],
'level': 'WARN'},
'loggers': {
"django.db": {"level": "WARN"}}})
app_config = AppConfig(NAME, sys.modules['__main__'])
apps.populate([app_config])
django.setup()
original_new_func = ModelBase.__new__
@staticmethod
def patched_new(cls, name, bases, attrs):
if 'Meta' not in attrs:
class Meta:
app_label = NAME
attrs['Meta'] = Meta
return original_new_func(cls, name, bases, attrs)
ModelBase.__new__ = patched_new
def syncdb(model):
""" Standard syncdb expects models to be in reliable locations.
Based on https://github.com/django/django/blob/1.9.3
/django/core/management/commands/migrate.py#L285
"""
connection = connections[DEFAULT_DB_ALIAS]
with connection.schema_editor() as editor:
editor.create_model(model)
main()
Gracias por esta solución. Desafortunadamente, esto no funciona todo el tiempo. En caso de que desee trabajar con 'select_related()' ahora o en el futuro, o tal vez para asegurarse de que también maneja otros tipos de magia que pueden ocurrir en cualquier otro lugar, debe extender la prueba de la siguiente manera: 'if hasattr (object, 'onetoonerevrelattr') y object.onetoonerevrelattr! = None' –
Tenga en cuenta que en Python <3.2, 'hasattr' tragará * todas * las excepciones que ocurran durante la búsqueda de la base de datos, y no solo' DoesNotExist'. Esto probablemente esté roto, y no es lo que quieres. –
no funciona con python 2.7. Incluso si OneToOne no existe, devuelve un objeto django.db.models.fields.related.RelatedManager. – alexpirine