Can I give the same name for different Models in different apps?
Can I give the same name for different Models in different apps? and What conflicts can happen?
After I have a try.. I got this Error:
Error: One or more models did not validate:
playlist.playlist: Accessor for field 'user'开发者_运维技巧 clashes with related field 'User.playlist_set'. Add a related_name argument to the definition for 'user'.
audio_playlist.playlist: Accessor for field 'user' clashes with related field 'User.playlist_set'. Add a related_name argument to the definition for 'user'.
Of course you can do that. There won't be any conflicts because tables are stored internally as appname_modelname
; let's say you have a model named Post
in an app named blog
and a model named Post
in an app named messages
. Tables will be stored as blog_post
and messages_post
. Also, the python classes are named project.blog.models.Post
and project.messages.models.Post
, so no conflict here either.
EDIT: Also, to be able to import them both in one file, use something like this:
import blog.models.Post as BlogPost
import messages.models.Post as MessagesPost
(or any names that make sense)
It's true that at the database level this will cause no issues.
You WILL run into problems with your URL routes and internal view names, though!
Assume you have two apps--"blog" and "comments" and each has a model named Message, and each Message model has a corresponding ModelViewSet (BlogMessageViewSet and CommentMessageViewSet, respectively)
The Django router will automatically name your view names message-list
, message-detail
, etc... with no regard for which app that model is in. So you will have collisions after you load these into your router since you have two models named 'Message'. For example, if in urls.py my router looked like this:
router = routers.DefaultRouter()
router.register(r'blog/message', BlogMessageViewSet)
router.register(r'comment/message', CommentMessageViewSet)
Then internally both the routes for /blog/message and /comment/message will point to /comment/message since that was registered last with the router and internally the view names will be message-list
, message-detail
, etc...
You can resolve this issue by giving a different base name to one of your views though like this:
router = routers.DefaultRouter()
router.register(r'blog/message', BlogMessageViewSet, view_name='blogmessage')
router.register(r'comment/message', CommentMessageViewSet)
Though this will require you to explicit define the url as a HyperlinkedIdentityField on the serializer for BlogMessageViewSet if you are using a HyperlinkedModelSerializer and to make all references to this view in urlresolvers.reverse() or other url-based tools use the view name 'blockmessage.'
Yes, I have done the same thing in one of my projects. If models have ForeignKey fields, like- BolgPost.author , then you have to give related_name to them.
author = models.ForeignKey(User,related_name='eu_author', on_delete=models.CASCADE)
Django is built on Python. Each app has it's own namespace.
精彩评论