Combining a request on one line with Django

Let's say I have a very simple model, which is a list of words:

class WordList(models.Model): word = models.CharField(max_length=60) 

After the user submits the form, I want ...

  • Get four random words
  • Combine them in one line
  • Make sure the duplicate line has not yet been generated, and if so, run it again
  • Store it in the database when it is good
  • Returns the result to the user.

I know how to get four random words:

 WordList.objects.order_by('?')[:4] 

I know how to make this a context and return it to the template, after which I can do everything with it, but I'm at a standstill about how I do it behind the scenes so that I can do the rest of my stuff before returning it to the user. The final line should look like this:

 these-are-my-words 

Also, where in my application am I doing this? I came from PHP and there, I would have a functions.php file or something to execute the backend and not interfere with the presentation. I found several other posts from people claiming to use functions.py , but I'm not sure how to include external pages that are not in the same folder as the existing views.py . If I do this:

 from functions import myfunc 

It only works if functions.py is in the folder where I import it.

+4
source share
3 answers

To include your query in a string, use the python join function .

 your_string = '-'.join([str(i) for i in WordList.objects.order_by('?')[:4]]) 

I suspect that this code should really live in one of your views and never touch your database, but it's hard to say without knowing what your application does. (Of course, you pass this line to the template and render it on the html page?)

+9
source

Here's what ended up working. The trick was that I didn’t realize that QuerySet could just access how it would be a Python list.

 dbQuery = WordList.objects.order_by('?')[:4] result = dbQuery[0] for word in dbQuery[1:]: result = "%s-%s" % (result, word) 

I feel that there must be a better way to do this. Joining, as suggested, did not help, I kept getting an error message, waiting for the line, even if all the documents say that it was used to combine lists, not lines, so I'm not sure where the breakdown was.

0
source

As long as your published solution "works", this is a very easy way to PHP.

Another Django way:

In your models models.py file:

 from django.db import models class Word(models.Model): word = models.CharField(max_length=60, blank=False, null=False, unique=True) def __unicode__(self): return u'%s' % self.word class RandomWordString(models.Model): string = models.CharField(max_length=255, blank=False, null=False, unique=True) def __unicode__(self): return u'%s' % self.string @staticmethod def generate(length): words = Word.objects.order_by('?')[:(length + 1)] possible_word_string = '-'.join(words.values_list('word', flat=True)) try: RandomWordString.objects.get(string=possible_word_string) # See if we've already generated this sequence return RandomWordString.generate(length) # Call ourselves again if we have except RandomWordString.DoesNotExist: return possible_word_string # If we haven't, return the value def save(self, *args, **kwargs): if not self.string or len(self.string) < 1: self.string = RandomWordString.generate(3) super(RandomWordString, self).save(*args, **kwargs) 

Then from any view or anywhere else:

 from words.models import RandomWordString seq = RandomWordString.generate(3) 

Since we overloaded the save, we can also just do:

 from words.models import RandomWordString string = RandomWordString.objects.create() string.save() 

This puts all the logic in the models themselves, which is slightly better than having it in the view (although this is completely a matter of taste).

In addition to what I posted, you will also want to add some logic to RandomWordString.generate to make sure you are not looping endlessly.

0
source

All Articles