关系中Django模型的related_name的字符限制是什么?

时间:2012-05-07 10:07:58

标签: python django django-models

我注意到-中没有+/*related_name或任何其他数学字符符号。您也无法使用:|.

如果你在related_name中有任何上述字符,虽然Django的models.py会验证,但每当你进行查询查询时,它都会抛出错误,如

Q(userprofile.user__place__managers=user)
SyntaxError: keyword can't be an expression

我想使用特殊字符的原因是因为我希望以related_name的形式拥有{class_name}{field_name}。因此,例如对于UserProfile模型类,我会做类似

的操作
class UserProfile(models.Model)
    user = models.OneToOneField(User, related_name='userprofile-user')
    user_type = models.ManyToManyFields(UserType, related_name='userprofile-user_type')

当我执行一个涉及后续关系的查询时,但仍然知道如何我向后追踪它。例如,如果我只是做

user_type = models.ManyToManyFields(UserType, related_name='user_type')

然后我可以UserTypeUser访问User.objects.get(pk=1).user_type.all()。但这使得user_type看起来像是User的字段。

相反,如果我可以执行User.objects.get(pk=1).userprofile-user_type.all()之类的操作,那么我就知道我将从User转到UserProfile再到UserType

我的思维方式可能属于少数,我认为大多数人只会做related_name='user_type'或甚至使用默认user_type_set

另一个问题是:命名related_name的好方式是什么?

1 个答案:

答案 0 :(得分:2)

userprofile-user_type 不是有效的python标识符。

Python认为你试图从userprofile中减去user_type。

在您的具体情况下,profiles将是一个足够好的相关经理名称。

这样当你有一个UserType实例时:

utype = UserType.objects.get(...)
utype.profiles.all()

它会为您提供与该用户类型相关联的所有配置文件。

此外没有ManyToManyField * s *,请删除“s”。

尽量不要比传达关系含义所需要的更冗长。 相关名称中的字段名称是多余的,不必要。

<强>更新 请不要将其命名为userprofiles_from_user_type

就像这样:

class Person:
    def PersonWalk(self):
        ...

而不是:

class Person:
    def walk(self):
        ...

让我用中间表

给你一个更复杂的例子
class Service(Model):
    name = models.CharField(max_length=32)

class Person(Model):
    services = models.ManyToManyField('self', through='PersonServiceRel', null=True, related_name='friends', symmetrical=False)

class PersonServiceRel(Model):
    provider = models.ForeignKey(Person, related_name='provided_services')
    consumer = models.ForeignKey(Person, related_name='consumed_services')
    service = models.ForeignKey(Service)

现在让我们说我们有人为彼此提供某种服务,我想要 知道用户“rantaplan”是否提供“跟踪”服务以及向谁提供服务。

rantaplan = Person.objects.get(name='rantanplan')
tracking = Service.objects.get(name='tracking')
PersonServiceRel.objects.filter(provider=rantaplan, service=tracking)
# or
rantaplan.provided_services.filter(service=tracking)

注意PersonServicesRel字段'provider'和'consumer'及其related_manager。 还要注意必要的查询。我认为它很可读。

因此,我建议您根据目的和用途命名您的字段和相关管理人员,尽可能少详细。