Django пометка select_related - PullRequest
       29

Django пометка select_related

0 голосов
/ 28 марта 2012

Я использую Django tagging project.

Это был очень стабильный проект.Работаю над django 1.3.

Но у меня проблема.

# in models.py
from tagging.fields import TagField
class Blog(models.Model):
     title = models.CharField(max_length = 300)
     content = models.TextField()
     tags = TagField()
     author = models.ForeignKey(User)

# in views.py
def blog_list(request):
    # I Want to use select related with tags
    blogs = Blog.objects.all().select_related("user", "tags") # ????
    ....

# in Templates
{% load tagging_tags %}
{% for blog in blogs %}
    {% tags_for_object blog as tags %}
    {{blog.title}}
    {% for tag in tags %}
        <a href="{% url tag_detail tag_id=tag.pk %}">{{tag}}</a>
    {% endfor %}
{% endfor %}

Ответы [ 2 ]

2 голосов
/ 30 марта 2012

django-tagging использует общий внешний ключ для вашей модели, поэтому вы не можете просто использовать select_related.

Что-то вроде этого должно помочь, хотя:

from django.contrib.contenttypes.models import ContentType
from collections import defaultdict
from tagging.models import TaggedItem

def populate_tags_for_queryset(queryset):
    ctype = ContentType.objects.get_for_model(queryset.model)
    tagitems = TaggedItem.objects.filter(
        content_type=ctype,
        object_id__in=queryset.values_list('pk', flat=True),
    )
    tagitems = tagitems.select_related('tag')
    tags_map = defaultdict(list)
    for tagitem in tagitems:
        tags_map[tagitem.object_id].append(tagitem.tag)
    for obj in queryset:
        obj.cached_tags = tags_map[obj.pk]
0 голосов
/ 30 января 2017

Недавно я столкнулся с той же проблемой и решил ее без единого запроса в БД.Действительно, нам не нужен тег id для получения URL.Так как имя тега уникально и имеет значение db_index, вы можете получить URL, используя name field вместо id .Например,

# your_app/urls.py

url(r'tag/(?P<tag_name>[-\w]+)$', tag_detail_view, name='tag_detail')

Кроме того, тегирование TagField дает нам строку с именами тегов, например 'python, django' .Таким образом, мы можем написать собственный шаблонный фильтр:

# your_app/templatetags/custom_tags.py

from django.urls import reverse

@register.filter
def make_tag_links(tags_str):
    return ', '.join([u'<a href="%s">%s</a>' % (reverse(
        'tag_detail', args=[x]), x) for x in tags_str.split(',')])

И тогда вы можете написать в шаблоне:

# your_list_template.html

{% for blog in blogs %}
    {{blog.title}}
    {% if blog.tags %}
        {{ blog.tags|make_tag_links|safe }}
    {% endif %}
{% endfor %}
...