Mi piace la risposta di Joctee , perché è così semplice.
if hasattr(request.user, 'type1profile'):
elif hasattr(request.user, 'type2profile'):
else:
Altri commentatori hanno espresso la preoccupazione che potrebbe non funzionare con alcune versioni di Python o Django, ma la documentazione di Django mostra questa tecnica come una delle opzioni:
Puoi anche usare hasattr per evitare la necessità di catturare eccezioni:
>>> hasattr(p2, 'restaurant')
False
Naturalmente, la documentazione mostra anche la tecnica di cattura delle eccezioni:
p2 non ha un ristorante associato:
>>> from django.core.exceptions import ObjectDoesNotExist
>>> try:
>>> p2.restaurant
>>> except ObjectDoesNotExist:
>>> print("There is no restaurant here.")
There is no restaurant here.
Sono d'accordo con Joshua sul fatto che cogliere l'eccezione rende più chiaro cosa sta succedendo, ma mi sembra solo più complicato. Forse questo è un ragionevole compromesso?
>>> print(Restaurant.objects.filter(place=p2).first())
None
Si tratta solo di interrogare gli Restaurant
oggetti in base al luogo. Ritorna None
se quel posto non ha ristorante.
Ecco uno snippet eseguibile per giocare con le opzioni. Se hai installato Python, Django e SQLite3, dovrebbe essere eseguito. L'ho testato con Python 2.7, Python 3.4, Django 1.9.2 e SQLite3 3.8.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):
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):
return "%s the restaurant" % self.place.name
class Waiter(models.Model):
restaurant = models.ForeignKey(Restaurant)
name = models.CharField(max_length=50)
def __str__(self):
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)
try:
print(p2.restaurant)
except ObjectDoesNotExist:
print("There is no restaurant here.")
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().')
print(Restaurant.objects.filter(place=p2).first())
def setup():
DB_FILE = NAME + '.db'
with open(DB_FILE, 'w'):
pass
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()
select_related()
ora o in futuro - o forse anche per essere sicuro di gestire anche altri tipi di magia che potrebbero accadere altrove - devi estendere il test come segue:if hasattr(object, 'onetoonerevrelattr') and object.onetoonerevrelattr != None