2012-05-07 53 views
0

我注意到你不能有-,+,/,*related_name中的任何其他數學符號。您也不能使用:,|.關係中Django模型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') 

那麼我就可以從UserUser.objects.get(pk=1).user_type.all()訪問UserType。但是這使得它看起來像user_typeUser的字段。

相反,如果我可以做一些像User.objects.get(pk=1).userprofile-user_type.all()那麼我會知道我從UserUserProfileUserType

那麼我的思維方式可能是少數,我認爲大多數人只會做related_name='user_type'或甚至使用默認user_type_set

另一個問題是:命名爲related_name的好方法是什麼?

+1

答案有很好的信息,但它的意思很長,很難撇清。對於TL; DR人羣:只需堅持(小寫)阿爾法和下劃線。 –

回答

2

userprofile-user_type不是有效的Python標識符。

Python認爲你正試圖從userprofile中減去user_type。

在您的具體情況profiles將是一個足夠好的相關經理姓名。

所以,當你有一個用戶類型的實例:

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

它會給你與該用戶類型相關聯的所有配置文件。

此外,沒有ManyToManyField * s *,刪除「s」。

儘量不要比傳達關係含義所需要的更冗長。 相關名稱中的字段名稱是多餘且不必要的。

UPDATE: 請不要將其命名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字段的提供者和消費者及其related_manager。 另請注意必要的查詢。我認爲它很可讀。

所以我建議你根據他們的目的和使用情況命名你的領域和相關的經理,儘可能少的冗長。

+0

我正在考慮使用'userprofiles_from_user_type'作爲'related_name'。這有點長,但對我來說似乎真的有意義。你寫道:「相關名稱中的字段名稱是多餘的和不必要的」。那麼'related_name'的命名方案是什麼? – hobbes3

+0

@ hobbes3我更新了我的答案。如果您需要進一步解釋或更簡單的例子,請給我留言 – rantanplan