In Django you describe data with ORM models, apply them to the database with migrations, and read and write it through QuerySets. User input is validated with forms, and state that lasts across requests is handled by sessions and the authentication system.
Models and relationships
Each attribute on a model class becomes a column in its table. ForeignKey creates a many-to-one relationship, ManyToManyField a many-to-many one, and OneToOneField a one-to-one one.
# polls/models.py
from django.db import models
from django.utils import timezone
class Question(models.Model):
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField(default=timezone.now)
class Meta:
ordering = ["-pub_date"]
def __str__(self):
return self.question_text
class Choice(models.Model):
question = models.ForeignKey(Question, on_delete=models.CASCADE, related_name="choices")
choice_text = models.CharField(max_length=200)
votes = models.PositiveIntegerField(default=0)
on_delete decides what happens when the referenced row is deleted: CASCADE deletes this one too, PROTECT blocks it, and SET_NULL clears the field (needs null=True). related_name sets the name for the reverse lookup, as in question.choices.all().
Migrations
After changing your models, apply the change to the database in two steps.
# Detect model changes and write a file into migrations/
python manage.py makemigrations polls
# Show the SQL that will run
python manage.py sqlmigrate polls 0001
# Apply it to the database
python manage.py migrate
# List migrations and whether they are applied
python manage.py showmigrations
Commit migration files with your code so teammates and servers get the same schema from migrate. The default database is SQLite; production deployments often use PostgreSQL, and switching is a matter of changing DATABASES.
Querying with QuerySets
Model.objects is a manager, and the QuerySets it returns are lazy. Chaining filters runs no queries; the database is hit once, when you iterate over the QuerySet or turn it into a list.
from datetime import timedelta
from django.db.models import Count, F, Q
from django.utils import timezone
from polls.models import Choice, Question
# Create and save
q = Question.objects.create(question_text="What is your favorite language?")
q.choices.create(choice_text="Python")
# Filter with field__lookup syntax
recent = Question.objects.filter(pub_date__gte=timezone.now() - timedelta(days=7))
python_q = Question.objects.filter(question_text__icontains="python")
# Follow relations and annotate with a count
popular = (
Question.objects.annotate(total=Count("choices"))
.filter(total__gt=1)
.order_by("-total")
)
# OR conditions and an atomic increment
Question.objects.filter(Q(question_text__startswith="Why") | Q(question_text__startswith="How"))
Choice.objects.filter(pk=1).update(votes=F("votes") + 1)
# Avoid N+1 queries
for choice in Choice.objects.select_related("question"):
print(choice.question.question_text)
0 Kommentare
Anmelden · Melde dich an, um einen Kommentar zu schreiben.