Defining django models in an alphabetic order - django

Can I define django models in an alphabetic order?
Models taken from django tutorial:
from django.db import models
class Question(models.Model):
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
class Choice(models.Model):
question = models.ForeignKey(Question)
choice_text = models.CharField(max_length=200)
votes = models.IntegerField(default=0)
I'd like for Choice to be defined before the Question. After simple reordering
class Choice(models.Models):
question = models.ForeignKey(Question)
question = models.ForeignKey(Question)
choice_text = models.CharField(max_length=200)
votes = models.IntegerField(default=0)
class Question(models.Models):
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
Fails, because I need Question before telling interpreter what it is.
Adding simple empty
class Choise(models.Model): pass
class Question(models.Model): pass
causes django to scream and still fail python manage.py makemigrations polls.
Is there a hack to define models in alphabetical order?
Or should I forfeit this idea and just define from totally unrelks ated to related to everything?
NOTE:
according to Sayse, the workarounds break IDEs in that IDE can't know whether you mean literal string or if you are looking for a class.

If you need to create a relationship on a model that has not yet been defined, you can use the name of the model, rather than the model object itself:
question = models.ForeignKey('Question')
instead of
question = models.ForeignKey(Question)
From https://docs.djangoproject.com/en/1.8/ref/models/fields/#django.db.models.ForeignKey

You can reference a model that has not been yet declared using quotes:
class Choice(models.Models):
question = models.ForeignKey('Question')
choice_text = models.CharField(max_length=200)
votes = models.IntegerField(default=0)
class Question(models.Models):
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')

Related

django admin ordering not working

in this as you can saw we change order 1, and order 0
while running it still the same
you can saw
using the shell
title at top and Whats the deal with strings?
while this has to be reverse according to the order`
Courses/model.py
from django.db import models
# Create your models here.
class Course(models.Model):
created_at = models.DateTimeField(auto_now_add=True)
title = models.CharField(max_length=255)
description = models.TextField()
def __str__(self):
return self.title
class Step(models.Model):
title = models.CharField(max_length=255)
description = models.TextField()
order = models.IntegerField(default=0)
course = models.ForeignKey(Course)
class Meta:
ordering = ['order', ]
You have an indentation error. The Meta class for Step, which contains the ordering directive, is not actually inside the Step class. It needs to be indented one level.

Creating a variable field in model Django

I want to ask the user how many questions they want to ask; based on their response, I want to populate a model with those many fields. The way I am currently thinking about doing that is as follows:
from __future__ import unicode_literals
from django.db import models
class Interview(models.Model):
title = models.TextField()
description = models.TextField()
number_questions = models.IntegerField()
question_one = models.ForeignKey('Question', related_name='question_one')
question_two = models.ForeignKey('Question', related_name='question_two')
question_three = models.ForeignKey('Question', related_name='question_three')
question_four = models.ForeignKey('Question', related_name='question_four')
question_five = models.ForeignKey('Question', related_name='question_five')
class Question(models.Model):
question_description = models.TextField()
prep_time = models.IntegerField()
response_time = models.IntegerField()
I realize that this solution is inefficient because a) the user is limited to a preset number of questions and b) if the user specifies less than 5 questions, there are unnecessary question entries created. What is a better way to go about storing multiple questions?
Do the foreign key relation the other way round. That's how you model a many-to-one relation:
class Interview(models.Model):
title = models.TextField()
description = models.TextField()
#property
def number_questions(self):
return self.questions.count()
class Question(models.Model):
interview = models.ForeignKey(Interview, related_name='questions')
question_description = models.TextField()
prep_time = models.IntegerField()
response_time = models.IntegerField()
Now you can access an interview's question via:
interview.questions.all()
An Interview can now have any number of Questions.
Btw, the related_name of all the ForeignKeys in your original Interview model should have been 'interview' to make any semantic sense.

What's the pros and cons of ForeignKey instead of ManyToManyField

In django tutorial it's modeled a poll structure:
from django.db import models
class Question(models.Model):
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
class Choice(models.Model):
question = models.ForeignKey(Question, on_delete=models.CASCADE)
choice_text = models.CharField(max_length=200)
votes = models.IntegerField(default=0)
but I always wonder why they don't implement like ManyToMany relation:
from django.db import models
class Question(models.Model):
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
choices = models.ManyToManyField(Choice)
class Choice(models.Model):
choice_text = models.CharField(max_length=200)
votes = models.IntegerField(default=0)
What are the pros and cons?
I'm sure they used a ForeignKey (One To Many) relationship in the tutorial because they were trying to keep the example as simple as possible, with only two models: Question and Choice. Notice that votes is a field of the Choice model, which makes it very simple to show the results of the poll.
If you were doing a poll where you had the same choices for every question (Strongly Agree, Somewhat Agree, etc.), then a ManyToMany relationship might be appropriate. But that makes things more complicated. Your proposed models for a ManyToMany relationship were:
from django.db import models
class Question(models.Model):
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
choices = models.ManyToManyField(Choice)
class Choice(models.Model):
choice_text = models.CharField(max_length=200)
votes = models.IntegerField(default=0)
But this wouldn't work correctly without some changes.votes is still a field of the Choice table, but now each choice applies to many questions. You would be able to see that the Strongly Agree choice got 38 votes, but you couldn't tell which questions the voters agreed with. To be able to tabulate the votes correctly, you would have to do something like
from django.db import models
class Question(models.Model):
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
choices = models.ManyToManyField('Choice', through='QuestionChoices')
class Choice(models.Model):
choice_text = models.CharField(max_length=200)
class QuestionChoices(models.Model):
question = models.ForeignKey(Question, on_delete=models.CASCADE)
choice = models.ForeignKey(Choice, on_delete=models.CASCADE)
votes = models.IntegerField(default=0)
Now you can tabulate exactly how many people voted for each question-choice combination, but it's more complicated and not very suitable for a getting-started tutorial.
With the ManyToMany models that you proposed, Django would automatically create the QuestionChoices model behind the scenes, but in order to attach the votes field to it you have to do it explicitly yourself.
If you have a relationship that could be modeled as either OneToMany or ManyToMany, the pros and cons depend on your particular application. In general you want to use a model that most accurately reflects the real-life situation. But you also have to consider how you need to update and summarize the data, and try to arrive at the best compromise. In my experience there aren't many situations where the choice is difficult.

Working with multiple forms on a single page in Django

I'm new to Django and I'm having a hard time wrapping my head around how to deal with "nested" forms in a template and how to process those forms accordingly. I'm creating a polling application similar to the tutorial, but more complex. I have multiple models (Poll, Question, Choice, Vote). A poll contains many questions, a question contains many choices.
I want to allow a user to view all the questions in a poll at once and vote on each question by selecting a choice from each question's choice set. After the user selects a choice for each question, they submit all their votes at once and process them to create the vote objects.
I'm really scratching my head at how to do this. Any help would be greatly appreciated.
Here are how my models are set up:
models.py
class Poll(models.Model):
name = models.CharField(max_length=255, default="Unnamed Poll")
key = models.CharField(max_length=16, blank=True, editable=False, unique=True, db_index=True, null=True)
instructor = models.ForeignKey(User)
course = models.ForeignKey(Course)
active = models.BooleanField(default=False)
anonymous = models.BooleanField(default=True, help_text="Allow votes to be anonymous?")
class Question(models.Model):
question_text = models.CharField(max_length=255, verbose_name='Poll Question')
poll = models.ForeignKey(Poll)
class Choice(models.Model):
question = models.ForeignKey(Question)
choice_text = models.CharField(max_length=255, verbose_name='Response Choice')
class Vote(models.Model):
question = models.ForeignKey(Question)
choice = models.ForeignKey(Choice)
student = models.ForeignKey(User)
You should use django.forms.Formsets in your case.Read about formsets here
Please comment to ask for further clarifications.
cheers :-)

Modeling django model statistics

I'm working on a questionnaire model for django that should be maintainable by someone with no programming experience, so I've spent a lot of time crafting my models to compensate for minor details.. Now I want to unlock the potential of SQL database queries to be able to generate statistics about the responses and feedback given.
One of my question types is a 5 star rating, so I would like to be able to gather statistics about the question like:
How many responses for question q were 5 star (, 4star, 3star, etc.)?
What was the average rating response?
Ideally I would like to record these statistic questions in a model, and create a view that shows all the statistics asked and keep the entire thing programmatic.
Should this be a carefully crafted model or set of models like feedback, or is there already some framework or module that handles these situations for me?
My questionnaire/models.py:
class QuestionType(models.Model):
name = models.CharField(max_length=256, blank=True, default="")
class Question(models.Model):
text = models.TextField()
type = models.ForeignKey(QuestionType)
class Response(models.Model):
question = models.ForeignKey(Question)
answer = models.TextField()
class Feedback(models.Model):
user = models.ForeignKey(User)
responses = models.ManyToManyField(Response)
response_time = models.DateTimeField(auto_now_add=True)
This would cover your requirements:
class QuestionType(models.Model):
name = models.CharField(max_length=256, blank=True, default="")
class Question(models.Model):
text = models.TextField()
type = models.ForeignKey(QuestionType)
def how_many_ratings_where_x_stars(self, stars):
return self.rating_set.filter(stars=stars).count()
def average_rating(self, stars):
return self.rating_set.aggregate(models.Avg('stars'))['stars__avg']
class Response(models.Model):
question = models.ForeignKey(Question)
answer = models.TextField()
user = models.ForeignKey(User)
timestamp = models.DateTimeField(auto_now_add=True)
class Rating(models.Model):
question = models.ForeignKey(Question)
stars = models.PositiveIntegerField(min_value=1, max_value=5)
user = models.ForeignKey(User)
timestamp = models.DateTimeField(auto_now_add=True)
class Meta:
unique_together = [('question', 'user')]