我想要一个很好的方便属性来执行以下操作:
from django.contrib.auth.models import User
user = User.objects.get(id=2)
user.company
<Company: Big Company L.L.C>
我目前正在使用lambda解决这个问题。在寻找答案时,似乎解决这个问题的“正确”方法可能是使用types.MethodType
,但我似乎无法理解它。是的,我读过Raymond excellent guide但我显然遗漏了一些东西..这是我目前对那些感兴趣的人的解决方案..
# Defined Elsewhere
class User:
name = models.CharField(max_length=32)
class Company(models.Model):
users = models.ManyToManyField(User, related_name="companies", blank=True, null=True)
# Here is the meat of this..
class UserProfile(models.Model):
"""This defines Users"""
user = models.OneToOneField(User)
def get_company(self):
try:
companies = self.user.companies.all()[0]
except (AttributeError, IndexError):
return None
User.company = property(lambda u: UserProfile.objects.get_or_create(user=u)[0].get_company())
现在这有效.. 但是有更好的方法 - 我对lambdas不是很疯狂吗?
答案 0 :(得分:1)
我不太确定我是否正确理解你的目标是什么,但从我认为理解的情况来看,似乎没有必要在这里使用描述符做任何疯狂的事情,更不用说types.MethodType
了。一个简单的属性很好,如果你不喜欢lambda,你可以使用一个用@property
装饰的普通函数:
class User:
name = models.CharField(max_length=32)
@property
def company(self):
return UserProfile.objects.get_or_create(user=self)[0].get_company())
修改:如果您无法触及User
类,则可以创建添加所需属性的派生类:
class MyUser(User):
@property
def company(self):
return UserProfile.objects.get_or_create(user=self)[0].get_company())
答案 1 :(得分:-1)
在@SvenMarnach的答案的基础上,你仍然可以在不使用lambda的情况下完成同样的事情。虽然你还需要猴子补丁:
def _get_user_company(user):
return UserProfile.objects.get_or_create(user=user)[0].get_company()
User.company = property(_get_user_company)