简体   繁体   中英

Django- how can I get the selections of a many-to-many field in my model's table?

I have a django model ( MyModel ) where one of the fields ( tags ) is a ManyToManyField field --tag's value is actually another model ( Tag ). When a user creates a MyModel instance/entry in the Django admin panel they choose at least one tag from a list of tags for that entry.

bytes/models.py

class Tag(models.Model):

    CATEGORY_CHOICES = (
        ('topic', 'topic')
    )

    tag = models.CharField(max_length=100, unique=True)
    category = models.CharField(max_length=100, choices=CATEGORY_CHOICES)


class MyModel(models.Model):

    id = models.CharField(max_length=30, primary_key=True)
    title = models.CharField(max_length=300, default='')
    author = models.CharField(max_length=300)
    copy = models.TextField(blank=True, default='')
    tags = models.ManyToManyField(Tag)

I'm trying to write a custom Django management task where I use SQL to get all of the data from MyModel (on a PSQL server):

import psycopg2

class Command(BaseCommand):

    def handle(self, *args, **options):
        config = settings.DATABASES['default']

        try:
          query = F'''SELECT * from bytes_mymodel'''

          conn = psycopg2.connect(..use config to connect to server)
          cursor = conn.cursor()

          cursor.execute(query)
          results = cursor.fetchall()
          print(results)

However when I print the 'results' I get a list of tuples - each tuple is a MyModel instance/entry. However, I don't see what tags are selected for the tags entry of each MyModel instance. For example:

[('abc', 'The Title Here', 'Written By', 'Lots of copy'), ('efg', 'The Second Title Here', 'Written By', 'Lots of copy')]

How can I get the tags selections for each MyModel entry through this Django management task? Should I be using something other than SQL? (maybe the Django ORM?)

By the way, if I were to use the dumpdata built-in Django management task I DO get the tags that were selected (as an array with the numbers that correspond to a tag). For example:

./manage.py dumpdata bytes.mymodel --indent 4 > static/bytes.json

outputs:

"fields": {
   "id": "abc"
   "title": "The Title Here"
   "author": "Written By"
   "copy": "Lots of copy"
   "tags": [3,5]
}

I guess the question is what are you going to do with the data after?

For a single instance from a model method for example you can do self.tag_set.all() (or replace tag_set with whatever related_name is set on the ManyToManyField for tags.

There's also values_list() which seems like a better solution for getting all MyModel and Tag relationships, even empty ones and multiple per instance.

MyModel.objects.values_list('id', 'title', 'author', 'copy', 'tags__tag')

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM