How Can I filter Django Models To Get Field Values From Different Tables

Viewed 28

I am working on Django Ticketing Application where I have a Pin Status Check View. And I want to query the Pin Model to know whether the PIN is activated, and if Activated query the Guest, and Profile Models to get the guest profile information and display in template.

I have been able to use Django Forms with search to display the PIN details but NOT able to figure out the logic code for getting the guest profile if PIN is ACTIVATED. Someone may wish to help. thanks.

Models code:

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE, null = True)
    surname = models.CharField(max_length=20, null=True)
    othernames = models.CharField(max_length=40, null=True)
    gender = models.CharField(max_length=6, choices=GENDER, blank=True, null=True)
    phone = PhoneNumberField()
    image = models.ImageField(default='avatar.jpg', blank=False, null=False, upload_to ='profile_images', 
)


    #Method to save Image
    def save(self, *args, **kwargs):
        super().save(*args, **kwargs)
        img = Image.open(self.image.path)
        #Check for Image Height and Width then resize it then save
        if img.height > 200 or img.width > 150:
            output_size = (150, 250)
            img.thumbnail(output_size)
            img.save(self.image.path)

       def __str__(self):
           return f'{self.user.username}-Profile'

class Pin(models.Model):
    ticket = models.ForeignKey(Ticket, on_delete=models.CASCADE)
    value = models.CharField(max_length=6, default=generate_pin, blank=True)
    added = models.DateTimeField(auto_now_add=True,  blank=False)
    reference = models.UUIDField(primary_key = True, editable = False, default=uuid.uuid4)
    status = models.CharField(max_length=30, default='Not Activated')

    #Save Reference Number
    def save(self, *args, **kwargs):
         self.reference == str(uuid.uuid4())
         super().save(*args, **kwargs) 

    def __unicode__(self):
        return self.ticket

    class Meta:
        unique_together = ["ticket", "value"]

    def __str__(self):
        return f"{self.ticket}"

    def get_absolute_url(self):
        return reverse("pin-detail", args=[str(self.id)])

class Guest(models.Model):
    guest_name = models.CharField(max_length=30, null=True)
    pin = models.CharField(max_length=6, null=True)


    def __str__(self):
        return f"{self.guest_name}" 

My Views:

def Pin_Searcht(request):
    context = {}
    #Search PIN Form
    searchForm = SearchEventTicketForm(request.GET or None)


    if searchForm.is_valid():
        #Value of search form
        value = searchForm.cleaned_data['value']
  

        user_pin = Pin.objects.filter(value=value)
    
      
    else:
        user_pin = Pin.objects.order_by('-added')[:2]
      
    page_title = "Search and Print PINs"
    context.update ({
    'page_title':page_title,
    'list_pins':paged_listPin,
    'searchForm':searchForm,
    'page_title':"PIN Status",

    })
    return render(request, 'user/pin_list.html', context)
1 Answers

I don't see any relation between the Pin Model and the Profile Models, I do see it in Guests

  • Guest.pin == Pin.value

If you want the search to Return Multiple Pins + Multiple Guests

# This is a Queryset (list of Pins)
#   [ <Pin #1> ]
user_pin_list = Pin.objects.filter(value=value)

# Get Guests with Pins (list)
#   [ <Guest #1> ]
guest_list Guest.objects.filter(pin__in=user_pin_list)

If you want the search to Return single Pin + single Guest

# Get Pin (Single)
#   <Pin #1>
user_pin_or_none = Pin.objects.filter(value=value).first()

# Get Guest with Pin (Single)
#   <Guest #1>
guest_or_none = Guest.objects.filter(pin=user_pin).first()

You could also just add a ForignKey to Pin in each Guests + Table Models:
class Pin(models.Model):
    value = models.CharField(max_length=6, default=generate_pin, blank=True)


class Profile(models.Model):
    # other fields
    pin = models.ForeignKey(Pin, on_delete=models.CASCADE)

class Guest(models.Model):
    # other fields
    pin = models.ForeignKey(Pin, on_delete=models.CASCADE)
and then use:
user_pin_or_none = Pin.objects.filter(value=value).first()

guest_or_none = Guest.objects.filter(pin=user_pin_or_none).first()
profile_or_none = Profile.objects.filter(pin=user_pin_or_none).first()

# -------------------------
# or you could do this: `__` allows you to filter fields in a ForeignKey (useful!)
guest_or_none = Guest.objects.filter(pin__value=value).first()
profile_or_none = Profile.objects.filter(pin__value=value).first()
Related