Как использовать значения полей по умолчанию для ForeignKey?
Я только начинаю изучать Django и строить на нем простой блог.
Итак, у меня есть две модели Post и PostStatistics. Когда я добавляю новый пост, я хочу, чтобы PostStatistics содержала все заданные по умолчанию значения. Как я могу добиться этого правильно?
models.py
class PostStatistics(models.Model):
id = models.UUIDField(primary_key=True, default=uuid4)
post_views = models.IntegerField(default=0)
post_likes = models.IntegerField(default=0)
post_favorites = models.IntegerField(default=0)
class Post(models.Model):
id = models.UUIDField(primary_key=True, default=uuid4)
user = models.ForeignKey(UserProfile, null=True, on_delete=models.CASCADE)
statistics = models.ForeignKey(PostStatistics, null=True, on_delete=models.CASCADE)
title = models.CharField(max_length=200)
body = RichTextField(blank=True, null=True)
draft = models.BooleanField(default=False)
views.py
def add_post(request: HttpRequest):
form = PostForm(request.POST)
is_draft = True if form.data.get("draft") == "on" else False
post = Post(
title=form.data["title"],
body=form.data["post"],
user=request.user,
draft=is_draft,
statistics = PostStatistics() -> this is not correct
)
post.save()
return redirect("post")
На данный момент я получаю FOREIGN KEY constraint failed.
Вы создаете новый:
def add_post(request: HttpRequest):
form = PostForm(request.POST)
is_draft = form.data.get('draft') == 'on'
post_statistics = PostStatistics.objects.create()
Post.objects.create(
title=form.data['title'],
body=form.data['post'],
user=request.user,
draft=is_draft,
statistics = post_statistics
)
return redirect('post')
Однако не имеет особого смысла хранить статистику в отдельной модели, поскольку существует четкая связь один-к-одному, и поэтому статистику можно хранить в модели Post.
Кроме того, вы можете использовать форму для проверки ввода и также создать объект (или, по крайней мере, его часть). Таким образом, лучшее моделирование может быть следующим:
from django.conf import settings
class Post(models.Model):
id = models.UUIDField(primary_key=True, default=uuid4)
user = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, on_delete=models.CASCADE, editable=False)
title = models.CharField(max_length=200)
body = RichTextField(blank=True, null=True)
draft = models.BooleanField(default=False)
post_views = models.IntegerField(default=0, editable=False)
post_likes = models.IntegerField(default=0, editable=False)
post_favorites = models.IntegerField(default=0, editable=False)
и затем работать с ModelForm, где вы позволяете форме сделать всю необходимую валидацию и очистку:
from django.contrib.auth.decorators import login_required
@login_required
def add_post(request: HttpRequest):
if request.method == 'POST':
form = PostForm(request.POST)
if form.is_valid():
form.instance.user = request.user
form.save()
return redirect('post')
else:
form = PostForm()
return render(request, 'name-of-some-template.html', {'form': form})
Note: It is normally better to make use of the
settings.AUTH_USER_MODEL[Django-doc] to refer to the user model, than to use theUsermodel [Django-doc] directly. For more information you can see the referencing theUsermodel section of the documentation.
Note: You can limit views to a view to authenticated users with the
@login_requireddecorator [Django-doc].