是的,你采取了正确的方法。通常当你想要一个解耦的实体,然后如果你想将属性与之关联(例如,用户的个人资料),OneToOneField
这是非常有用的。
至于连接,因为它们是两个单独的表,所以没有真正好的合并它们的方法。但是,由于您使用的是related_name
参数,即使模型不同,您也可以通过以下方式轻松访问其他模型的属性:
venue = Venue.objects.get(...)
venue.name <- Venue attribute
venue.venueProfile.foo <- VenueProfile attribute
这种方法的一个缺点是涉及到数据库查询。为了提高效率,您可以使用其中任何一种方法。然而,第一种方法更有效,因为为此,Django 将使用 SQL 连接,它比“Python 的”连接更快。
profile = VenueProfile.objects.filter(...).select_related('venue')[0]
venue = profile.venue <- no extra query
或者这里 Django 的这种方法将在 Python 中执行连接的速度很慢:
venue = Venue.objects.filter(...).prefetch_related('venueProfile')[0]
此时,这些只是常规对象,因此您可以轻松地将它们传递给模板。下面是一个简单的视图、urlconfig和模板示例:
def all_venues(request):
# note that querying profiles...
venues = VenueProfile.objects.all().select_related('venue')
return render_to_response('template.html', {'venues':venues})
def venue(request, venue_id):
venue = VenueProfile.objects.filter(venue__pk=venue_id).select_related('venue')
if len(venue) == 1:
venue = venue[0]
else:
raise Http404
...
网址配置:
url(r'^venue/all/$', 'all_venues', name='all_venues'),
url(r'^venue/(?P<venue_id>\d+)/$', 'venue', name='venue'),
和模板
{% load url from future %}
{% for venue_profile in venues %}
{% with venue=venue_profile.venue profile=venue_profile %}
<ul>
<li>
<a href="{% url 'venue' venue_id=venue.pk %}">
{{ venue.name }}</a><br>
<img href="{{ venue.image.url }}"><br>
{{ profile.foo }}
</li>
</ul>
{% endwith %}
{% empty %}
No venues
{% endfor %}