Django model: how to combine a reverse access set with two foreignkey fields?

In my django models file, I have:

class Node(models.Model):
   name = models.CharField(max_length=16)

class Segment(models.Model):
   start = models.ForeignKey(Node, related_name='start_segments')
   end = models.ForeignKey(Node, related_name='end_segments')

      

From a Node object, I would like to access all segment objects that have either a beginning or an end pointing to a node, from a single attribute name, e.g .:

node_x.segment_set

      

However, this is not possible as far as I could see. I have provided two different related_name-s to avoid the error that would otherwise occur. Otherwise, I would like to create one set that combines the two.

I can create a utility method that will return the combo set. However, it will not be available for inquiries. In my application, I often have to search for all the segments associated with a node.

+3


source to share


2 answers


To get QuerySet

you can use objects Q

(see Complex searches with Q objects ).

from django.db.models import Q
results = Segment.objects.filter(Q(start=node_x) | Q(end=node_x))

      

To access this faster, you can define it as property

:



from django.db import models
from django.db.models import Q

class Node(models.Model):
    name = models.CharField(max_length=16)

    @property
    def segments(self):
        return Segment.objects.filter(Q(start=self) | Q(end=self))

      

Now in your code, you can get the segments by accessing property

:

In [1]: print node_x.segments  # or print(node_x.segments) in Python 3
Out[1]: [<Segment: Segment object>, <Segment: Segment object>, ...]

      

+1


source


I think you should either use

Segment.objects.filter(start=node_x) | Segment.objects.filter(end=node_x)

      



or

node_x.start_segments.all() | node_x.end_segments.all()

      

+1


source







All Articles