1

Let's say I want to ask a User a Question: "Order the following animals from biggest to smallest". Here's a little simplified django:

class Question(models.Model):
    text = models.CharField()         #eg "Order the following animals..."

class Image(models.Model):
    image = models.ImageField()       #pictures of animals
    fk_question = models.ForeignKey(Question)

Now I can assign a variable number of Images to each Question, and customize the question text. Yay.

What would be the appropriate way to record the responses? Obviously I'll need foreign keys to the User and the Question:

class Response(models.Model):
    fk_user = models.ForeignKey(User)
    fk_question = models.ForeignKey(Question)

But now I'm stuck. How do I elegantly record the order of the Image objects that this User specified?

Edit: I'm using Postgres 9.5

e4c5
  • 52,766
  • 11
  • 101
  • 134
Escher
  • 5,418
  • 12
  • 54
  • 101

1 Answers1

1

I am generally strongly opposed to storing comma separated data in a column. However this seems like an exception to the rule! May I propose CommaSeparatedIntegerField?

class CommaSeparatedIntegerField(max_length=None, **options)[source]¶
A field of integers separated by commas. As in CharField, the max_length argument is required and the note about database portability mentioned there should be heeded.

This is essentially a charfield, so the order that you input will be preserved in the db.

You haven't mentioned your database. If you are fortunate enough to be on Postgresql and using django 1.9 you can use the ArrayField as well.

using arrayfield would be much better because then the conversion back and forth between string and lists would not be there. The case against comma separated fields is that searching is hard and you can't easily pull the Nth element. POstgresql arrays remove the latter difficulty.

e4c5
  • 52,766
  • 11
  • 101
  • 134
  • I'm using Postgres and 1.9.6 (probably upgrading to 1.10 in a few weeks). How would that change portability and performance? My intent is to be able to deliver this information for visualisation in d3.js via django-rest-framework; would this facilitate it better? – Escher Aug 02 '16 at 15:09
  • Another point: let's say I store the CSV: `1,3,2,5,4`. How do I know to which image each integer refers? Would `Image` need a Meta class with `ordering = ('id',)`? – Escher Aug 02 '16 at 15:11
  • Each image has it's primary key that's what needs to go into this ArrayField or comma field – e4c5 Aug 02 '16 at 15:13
  • Ooohh. So I guess that's going to have to end up in the POST data then? I keep reading "avoid exposing the pk to the client" ... any way around this without creating a separate field (like a uuid or something?) – Escher Aug 02 '16 at 15:22
  • See if you like this approach: http://stackoverflow.com/questions/37558821/how-to-replace-djangos-primary-key-with-a-different-integer-that-is-unique-for – e4c5 Aug 02 '16 at 15:23
  • glad to have been of help – e4c5 Aug 02 '16 at 15:26
  • Also of note: `CommaSeparatedIntegerField has been deprecated. Support for it (except in historical migrations) will be removed in Django 2.0. HINT: Use CharField(validators=[validate_comma_separated_integer_list]) instead.` – Escher Aug 04 '16 at 06:28
  • @Escher thank you for that. But after the discussions in the comments, the OP is now going to use ArrayField I believev. – e4c5 Aug 04 '16 at 06:49