ckcAdmin
ckcAdmin

Reputation: 65

Django - How to Filter when getting values_list?

I have an application that has multiple objects related to one Model. When I try and get data to display in a form (in order to update) it is either giving an error or not displaying any of the data.

To illustrate the layout we have OBJECT(ID):

Project(1):
    Issue(1)
    Issue(42)
    Issue(66)
    Issue(97)

What is happening above is I have multiple issues related to the project. I am getting the IDs from the Issues within the Project by using the following queryset.

get_issue_id = get_object_or_404(DevProjects, pk=pk)
issue_id = DevIssues.objects.filter(project=get_issue_id).values_list('id', flat=True)

Which returns:

<QuerySet [1, 42, 66, 97]>

I am trying to use the following queryset to filter the Issue ID from the values_list, in order to set the Instance= (for forms) to the queryset to only get the data and display that data in the form for the issues ID from the Project PK that I am requesting.

update_issue = DevIssues.objects.filter(id=issue_id)

Below is my current view.py

get_issue_id = get_object_or_404(DevProjects, pk=pk)
issue_id = DevIssues.objects.filter(project=get_issue_id).values_list('id', flat=True)
update_issue = DevIssues.objects.filter(id=issue_id)
update_issue_form = UpdateProjectIssues(instance=update_issue)
if request.method == 'POST' and 'updateissue' in request.POST:
      update_issue_form = UpdateProjectIssues(request.POST, instance=update_issue)
            if update_issue_form.is_valid():
                update_issue_form.save()

Here is models.py for both DevProjects and DevIssues:

class DevProjects(models.Model):
    PROJECT_TYPE = [
        ('NEW_APP', 'New Application'),
        ('UPDATE_APP', 'Update Application'),
        ('BUG_FIX', 'Bug Fixes')
    ]
    PROJECT_STATUS = [
        ('New', 'New'),
        ('In Progress', 'In Progress'),
        ('Complete', 'Complete'),
    ]
    project_id = models.CharField(max_length=15, editable=False)
    project_title = models.CharField(max_length=100)
    project_desc = models.CharField(max_length=500)
    project_category = models.CharField(max_length=25, choices=PROJECT_TYPE, null=True, blank=True)
    project_status = models.CharField(max_length=25, choices=PROJECT_STATUS, default='New')
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateField(auto_now=True)
    created_by = models.ForeignKey(User, on_delete=models.CASCADE)

    def save(self, *args, **kwargs):
        super(DevProjects, self).save(**kwargs)
        self.project_id = 'PROJ-' + str(self.id)
        super(DevProjects, self).save(**kwargs)

    def __str__(self):
        return self.project_title


class DevIssues(models.Model):
    ISSUE_CODE = [
        ('BUG', 'Bug'),
        ('BACKLOG', 'Backlog'),
        ('REQUEST', 'Request'),
        ('TODO', 'To-Do'),
    ]
    ISSUE_STATUS = [
        ('New', 'New'),
        ('In Progress', 'In Progress'),
        ('Complete', 'Complete'),
    ]
    issue_id = models.CharField(max_length=15, editable=False)
    project = models.ForeignKey(DevProjects, on_delete=models.CASCADE, related_name='issue')
    issue = models.CharField(max_length=100)
    issue_desc = models.CharField(max_length=500)
    issue_code = models.CharField(max_length=9, choices=ISSUE_CODE, null=True, blank=True)
    issue_status = models.CharField(max_length=15, choices=ISSUE_STATUS, default='New')
    issue_resolution = models.CharField(max_length=500, null=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateField(auto_now=True)
    created_by = models.ForeignKey(User, on_delete=models.CASCADE)

    def save(self, *args, **kwargs):
        self.issue_id = 'ISSUE-' + str(self.id)
        super(DevIssues, self).save(**kwargs)

Here is my forms.py:

class UpdateProjectIssues(forms.ModelForm):
    class Meta:
        model = DevIssues
        fields= ["issue", "issue_desc", "issue_code", "issue_status"]
        labels = {
            'issue_status': 'Update Status'
        }

And this is the current error I am facing:

'QuerySet' object has no attribute '_meta'

When I use get(), this is the error I get:

The QuerySet value for an exact lookup must be limited to one result using slicing.

Another error I get when I use something like id__in:

get() returned more than one DevIssues -- it returned 2!

How do I filter 'issue_id', the values_list queryset, in order to get the data and display the correct data within the form?

Upvotes: 0

Views: 121

Answers (1)

Md Shahbaz Ahmad
Md Shahbaz Ahmad

Reputation: 1166

To get project instance

project_id = get_object_or_404(DevProjects, pk=pk)

To get issue_ids related to that project instance

issue_ids = DevIssues.objects.filter(project=project_id).values_list('id', flat=True)

To get update issue objects

update_issue = DevIssues.objects.filter(id__in=issue_ids)

but you already get the same result in this line

update_issue = DevIssues.objects.filter(project=project_id)

so, do not need IN qyery.

You got error because you pass queryset instead of object in this line

update_issue_form = UpdateProjectIssues(instance=update_issue)

You can iterate on queryset and pass object in ModelForm class.

Upvotes: 1

Related Questions