Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Update Django from 1.6 to 1.8: Invalid field name(s) given in select_related

I do update of project from Django 1.6.7 to 1.8.7 and I have got following exception with Django 1.8, although with Django 1.6 it code was right:

In[2]: from apps.route import models
In[3]: models.Trace.objects.select_related("trace_points")
Out[3]: <repr(<django.db.models.query.QuerySet at 0x3b50c10>) failed: django.core.exceptions.FieldError: Invalid field name(s) given in select_related: 'trace_points'. Choices are: user>

My models:

class Trace(SocialMixin, models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='traces')
    name = models.CharField(u'Название', max_length=255)
    rating = RatingField(range=5, weight=0)
    start_date = models.DateTimeField(u'Дата старта')
    finish_date = models.DateTimeField(u'Дата окончания', null=True, blank=True)
    distance = models.DecimalField(max_digits=15, decimal_places=6, null=True, blank=True)
    created = models.DateTimeField(auto_now_add=True)
    hits = generic.GenericRelation(HitCount, object_id_field='object_pk')
    description = models.TextField(null=True, blank=True)

class TracePoint(models.Model):
    country = models.ForeignKey(Country, null=True, blank=True)
    city = models.ForeignKey(City, null=True, blank=True)
    trace = models.ForeignKey(Trace, related_name="trace_points")

I also have this bug into DetailView on Trace, DetailView uses get_related_selections, and of course I got "FieldError: Invalid field name...", to avoid error I have to use ManyToManyField instead of ForeigenKey?

like image 738
Peter Avatar asked May 05 '16 09:05

Peter


2 Answers

Django 1.8 checks that the fields given in select_related are correct. The select_related method can be used for foreign keys and one to one fields. It is not possible to use it for the reverse relationship Trace back to TracePoint.

In previous versions of Django, Trace.objects.select_related("trace_points") would not raise an error, but the select_related() call would have no effect.

You can either remove the select_related() call, or replace it with prefetch_related, which will work.

Trace.objects.prefetch_related('trace_points')
like image 152
Alasdair Avatar answered Sep 17 '22 06:09

Alasdair


Django's select_related() doesn't works for backwards foreignkey relations.

You might want to use prefetch_related() for prefetching all trace points at python level.

models.Trace.objects.prefetch_related("trace_points")
like image 31
v1k45 Avatar answered Sep 18 '22 06:09

v1k45