Как найти объекты django в отношении manytomany (с помощью сквозной связи)?
Мне нужно найти услуги с ценами для каждого пользователя. Я определил свои модели:
class User(AbstractUser):
"""Default user model."""
username = None
email = models.EmailField(unique=True)
proposals = models.ManyToManyField(
Service,
through=Pricing,
blank=True)
class Service(models.Model):
name = models.CharField(max_length=50)
class Pricing(models.Model):
user = models.ForeignKey('users.User', on_delete=models.PROTECT)
service = models.ForeignKey(Service, on_delete=models.PROTECT)
price = models.IntegerField()
В моем шаблоне я могу получить пользователя с ассоциированным предложением с помощью этого цикла for
{% for proposal in object.proposals.all %}
{{ proposal }}
{% endfor %}
У меня нет цен, а только названия услуг. Что я упускаю?
Вы перечисляете object.pricing_set.all()
с:
{% for pricing in object.pricing_set.all %}
{{ pricing.service }}: {{ pricing.price }}
{% endfor %}
Однако это приведет к проблеме N+1, используя объект Prefetch
в представлении, мы можем избежать этого.
Если вы, например, получаете объект User
, вы можете предварительно получить pricing
s и связанные service
s с помощью:
User.objects.prefetch_related(
Prefetch('pricing_set', Pricing.objects.select_related('service'))
)
Если вы, таким образом, используете один User
с первичным ключом pk
, то это может быть реализовано следующим образом:
object = User.objects.prefetch_related(
Prefetch('pricing_set', Pricing.objects.select_related('service'))
).get(pk=some_pk)
Устанавливает related_name
поле внешнего ключа:
class Pricing(models.Model):
user = models.ForeignKey('users.User', on_delete=models.PROTECT, related_name='pricing_instances') # Replace 'pricing_instances' with what makes sense to you
service = models.ForeignKey(Service, on_delete=models.PROTECT)
price = models.IntegerField()
Тогда вы можете получить доступ к price
следующим образом:
{% for pricing_instance in object.pricing_instances.all %}
{{ pricing_instance.price }}
{% endfor %}