0

I'm looking at this tutorial from the Mozilla library. I want to create a list view in admin based on a database relationship. For example I have a Vehicle model and a statusUpdate model. Vehicle is a single instance with many statusUpdates. What I want to do is select the most recent statusUpdate (based on the dateTime field I have created) and have that data available to me in the list view.

The tutorial mentions:

class Vehicle(models.Model):

class statusUpdate(models.Model):
    vehicle = models.ForeignKey(Vehicle, on_delete=models.CASCADE)

Question: How could I do a list view with model relationships and be able to filter by fields on the child relationship and pass to the view?

user409938289
  • 97
  • 1
  • 12

2 Answers2

2

Here's what I wanted in a Class Based View (CBV), my explanation of my issue was not very clear.

def get_context_data(self, **kwargs):

get_context_data is a way to get data that is not normally apart of a generic view. Vehicle is already provided to the View because its the model defined for it, if you wanted to pass objects from a different model you would need to provide a new context, get_context_data is the way to do this. statusUpdate is a model with a foreign key to Vehicle. Full example below.

class VehicleDetail(generic.DetailView):
    model = Vehicle
    template_name = 'fleetdb/detail.html'


    def get_context_data(self, **kwargs):
        # Call the base implementation first to get a context
        context = super(VehicleDetail, self).get_context_data(**kwargs)
        context['updates'] = statusUpdate.objects.filter(vehicle_id=1).order_by('-dateTime')[:5]
        return context
user409938289
  • 97
  • 1
  • 12
0

I don't think that solves your problem entirely. You used this:

context['updates'] = statusUpdate.objects.filter(vehicle_id=1).order_by('-dateTime')[:5]

This will only result in a list of statusUpdates where vehicle_id is set to 1. The part I was struggling with is how to get the primary key (in your case the actual vehicle_id). I found this solution:

vehicle_id = context['vehicle'].pk # <- this is the important part
context['updates'] = statusUpdate.objects.filter(vehicle_id=vehicle_id).order_by('-dateTime')[:5]

I discovered the context object and it contains the data which has already been added (thus you need to call super before using it). Now that I write it down it seems so obvious, but it took me hours to realize.

Btw. I am pretty new to Django and Python, so this might be obvious to others but it wasn't to me.

AlexWerz
  • 739
  • 2
  • 9
  • 21
  • You're exactly right, the code I posted was eventually changed to include the pk of the vehicle. I forgot to update the code here. The hard coded '1' was me testing. – user409938289 Jan 10 '18 at 02:01
  • Good link for further reading https://stackoverflow.com/questions/36950416/when-to-use-get-get-queryset-get-context-data-in-django – user409938289 Jan 10 '18 at 02:26
  • Oh boy, I didn't wanted to add another answer. My text should have been a comment. Thanks for your reply. – AlexWerz Jan 10 '18 at 06:37