Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create lists in ListView from model field in django

I would like to use ListView to generate lists of degrees by school and state. For example, I would want to use to the degree_awarded field in the Program model to make a list of "Schools in Pennsylvania Where You Can Get A Bachelor Degree."

Models

class State(models.Model):
    state_name = models.CharField(max_length=20, default='')
    state_slug = models.SlugField()

    def __str__(self):
        return self.state_slug

class City(models.Model):
    city_name = models.CharField(max_length=55, default='')
    city_slug = models.SlugField()
    state = models.ForeignKey(State, null=True)

    def __str__(self):
        return self.city_slug

class School(models.Model):
    school_name = models.CharField(max_length=55, default='')
    school_slug = models.SlugField()
    city = models.ForeignKey(City, null=True)

    def __str__(self):
        return self.school_slug

    def sorted_programs(self):
        return self.program_set.all().order_by('program_name')

class Program(models.Model):
    program_name = models.CharField(max_length=100, default='')
    program_slug = models.SlugField(max_length=100, default='')
    school = models.ForeignKey(School, null=True)
    degree_awarded = models.CharField(max_length=10, default='')

    def __str__(self):
        return self.program_slug

Views

class SchoolIndexView(ListView):
    model = State

    def get_context_data(self, **kwargs):
        context = super(SchoolIndexView, self).get_context_data(**kwargs)
        context['state_list'] = State.objects.all().order_by('state_name')
        return context

class ProgramInSchoolView(DetailView):
    model = School
    template = 'school_detail.html'

    def get_object(self):
        school_slug = School.objects.get(
            school_slug=self.kwargs.get('school_slug')
        )
        return school_slug

    def get_context_data(self, **kwargs):
        context = super(ProgramInSchoolView, self).get_context_data(**kwargs)
        context['school'] = self.object
        context['program_list'] = self.object.program_set.all().order_by('program_name')

        return context

class ProgramView(DetailView):
    model = Program
    template = 'program_detail.html'

    def get_object(self):
        program_slug = Program.objects.get(
            program_slug=self.kwargs.get('program_slug')
        )
        return program_slug

    def get_context_data(self, **kwargs):
        context = super(ProgramView, self).get_context_data(**kwargs)
        context['program'] = self.object
        context['program_classes'] = self.object.classes_set.all().order_by('class_number')

        return context

class DegreeView(ListView):
    model = Program
    template = 'degree_list.html'

    def get_context_data(self, **kwargs):
        context = super(DegreeView, self).get_context_data(**kwargs)
        context['state_for_degree'] = State.objects.get(state_slug=self.kwargs.get('state_slug'))
        context['city_for_degree'] = City.objects.get(city_name=self.kwargs.get('city_name'))
        context['school_for_degree'] = School.objects.get(school_slug=self.kwargs.get('school_slug'))
        context['degree_by_state'] = Program.objects.get(degree_awarded=self.kwargs.get('degree_awarded')).filter(school_slug=school_slug).filter(city_slug=city_slug).filter(state_slug=state_slug).order_by('city_name')

        return context

Urls

    url(r'^(?P<state_slug>[\w-]+)/$', CityInStateView.as_view(), name='state_detail'),
    url(r'^(?P<state_slug>[\w-]+)/(?P<school_slug>[\w-]+)/$', ProgramInSchoolView.as_view(), name='school_detail'),
    url(r'^(?P<state_slug>[\w-]+)/(?P<school_slug>[\w-]+)/(?P<program_slug>[\w-]+)/$', ProgramView.as_view(), name='program_detail'),
    url(r'^(?P<state_slug<[\w-]+)/(?P<program_slug>[\w-]+)/$', DegreeView.as_view(), name='degree_list'),

I cannot figure out how to write the view and url routing so that I can use the information I already have in the degree_awarded field of the Program model to generate a list.

Can someone please point me in the right direction?

Thank you.

Edit: I've added the relevant model(s) that I left out before. I wanted to be concise. I've also added in the last filter that I tried. It is still not producing the degree lists sorted by state.

like image 459
user2901792 Avatar asked Jan 17 '26 19:01

user2901792


1 Answers

I don't think you need all that code in the get_context_data method. You should customize the list of objects to display in the get_queryset method.

class DegreeView(ListView):
    model = Program
    template = 'degree_list.html'

    def get_queryset(self):
        queryset = super(DegreeView, self).get_queryset()
        # batchelors degrees only
        queryset = queryset.filter(program_slug=self.kwargs['program_slug'])
        # filter by state
        queryset = queryset.filter(school__city__state__slug=self.kwargs['state_slug'])
        return queryset

See the docs on lookups that span multiple relationships to explain the school__city__state__slug filter.

Then in your template, you can loop through the programs, for example:

{% for program in object_list %}
{{ program.degree_awarded %}
like image 118
Alasdair Avatar answered Jan 20 '26 11:01

Alasdair