Django: How to write a function based view used for URL with parameter

Question:

I am learning Django, using function based views, and I am struggling with the following:
I have this path in urls.py

path('user/<str:username>',views.UserProjectList,name='user-projects')

that is supposed to show all the projects of the particular user (client). In order to reach it, username should be parameter of the function based view, however I am struggling how to write such view…
I have this:

def UserProjectList(request,username):
    user = User.objects.get(username=username) #THIS IS WRONG and should return id of the user
    #user = User.objects.filter(username=username) #also wrong

    tag_list = ProjectTagsSQL.objects.all() #ProjectTagsSQL and ProjectSQL are connected
    project_list = ProjectSQL.objects.filter(client=user) #ProjectSQL table has column client_id (pk is id in User) and table contains all the projects

    context = {
        'tagy' : tag_list,
        'projecty' : project_list
    }

    return render(request, 'home_page/user_projects.html', context) #SHOULD THE PARAMETER BE INCLUDED HERE?

I tried to inspire with the code from class based view I found on the internets (thats is working for me but i didnt manage to connect it with ProjectTagsSQL as i managed in FBV, but that’s a different problem) but i didnt manage

class UserProjectListView(ListView):
    model = ProjectSQL
    template_name = 'home_page/user_projects.html' 
    context_object_name = 'data'

    def get_queryset(self):
        user = get_object_or_404(User, username=self.kwargs.get('username'))
        return ProjectSQL.objects.filter(client=user)

Could someone help me how to deal with such function based view please? As this solution its not working (will return nothing for any user)

Here is also the ProjectSQL model (and ProjectTagsSQL model) :

class ProjectSQL(models.Model):
    id = models.AutoField(primary_key=True)
    country = models.TextField()
    city = models.TextField()
    time_added = models.DateTimeField(default=timezone.now)
    start_date = models.DateField()
    end_date = models.DateField()
    client = models.ForeignKey(User, on_delete=models.CASCADE)

    class Meta:
        managed = False #https://docs.djangoproject.com/en/4.0/ref/models/options/
        db_table = 'project'

class ProjectTagsSQL(models.Model):
    id = models.IntegerField(primary_key=True)
    project = models.ForeignKey(ProjectSQL, on_delete=models.CASCADE)
    tag = models.ForeignKey(ProjectTagSQL, on_delete=models.CASCADE)

    class Meta:
        managed = False  # https://docs.djangoproject.com/en/4.0/ref/models/options/
        db_table = 'project_tags'
Asked By: rebro

||

Answers:

You need to write user.id so:

from django.shortcuts import get_object_or_404

def UserProjectList(request,username):
    user = get_object_or_404(User,username=username)
    tag_list = ProjectTagsSQL.objects.all()
    project_list = ProjectSQL.objects.filter(client=user.id)

    context = {
        'tagy' : tag_list,
        'projecty' : project_list
    }

    return render(request, 'home_page/user_projects.html', context)

Also, try to check template variables’ name, whether you used same or not.

Note: Always append / at the end of every route so it should be path('user/<str:username>/'....

Note: Function based views are generally written in snake_case so it is better to name it as user_project_list instead of UserProjectList.

Answered By: Sunderam Dubey
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.