Tôi thích joctee's answer, bởi vì nó đơn giản như vậy.
if hasattr(request.user, 'type1profile'):
# do something
elif hasattr(request.user, 'type2profile'):
# do something else
else:
# do something else
bình luận khác đã dấy lên lo ngại rằng nó có thể không làm việc với một số phiên bản của Python hoặc Django, nhưng the Django documentation cho thấy kỹ thuật này là một trong những lựa chọn:
You can also use hasattr to avoid the need for exception catching:
>>> hasattr(p2, 'restaurant')
False
Tất nhiên, tài liệu cũng hiển thị kỹ thuật bắt ngoại lệ:
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.
Tôi đồng ý với Joshua rằng bắt ngoại trừ làm cho nó rõ ràng hơn những gì đang xảy ra, nhưng nó chỉ có vẻ hỗn độn với tôi. Có lẽ đây là một sự thỏa hiệp hợp lý?
>>> print(Restaurant.objects.filter(place=p2).first())
None
Đây chỉ là truy vấn đối tượng Restaurant
theo địa điểm. Nó trả về None
nếu địa điểm đó không có nhà hàng.
Dưới đây là một đoạn mã thực thi cho bạn để chơi với các tùy chọn. Nếu bạn đã cài đặt Python, Django và SQLite3, nó sẽ chỉ chạy. Tôi đã thử nghiệm nó với Python 2.7, Python 3.4, Django 1.9.2 và 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()
Cảm ơn bạn đã giải pháp này. Thật không may, điều này không làm việc tất cả các thời gian. Trong trường hợp bạn muốn làm việc với 'select_related()' ngay bây giờ hoặc trong tương lai - hay thậm chí có thể để chắc chắn bạn cũng xử lý các loại khác của ma thuật có thể xảy ra ở những nơi khác - bạn cần phải mở rộng các thử nghiệm như sau: 'nếu hasattr (đối tượng, 'onetoonerevrelattr') và object.onetoonerevrelattr! = None' –
Lưu ý rằng trong Python <3.2, 'hasattr' sẽ nuốt * tất cả * ngoại lệ xảy ra trong quá trình tra cứu cơ sở dữ liệu, và không chỉ' DoesNotExist'. Điều này có thể bị hỏng, và không phải những gì bạn muốn. –
không hoạt động với python 2.7. Ngay cả khi OneToOne không tồn tại, nó trả về một đối tượng django.db.models.fields.related.RelatedManager. – alexpirine