Как автоматически установить поток вместо того, чтобы пользователь устанавливал его в django
Я пытаюсь создать сайт дискуссионного форума на django. Все работает, но я хочу изменить одну вещь и понятия не имею, как это сделать.
На сайте пользователи могут создавать темы и сообщения в этих темах. Когда тема создана, в ней есть кнопка с надписью "Добавить сообщение в эту тему". После этого пользователь попадает на форму. В настоящее время, если бы форма работала, они должны были бы выбрать из выпадающего меню, в какую тему они хотят добавить сообщение. Я хочу, чтобы темой была та тема, внутри которой находится кнопка, на которую они нажали.
models.py:
class Thread(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
title = models.CharField(max_length=300)
description = models.CharField(max_length=1000)
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return str(self.title)
def get_absolute_url(self):
return reverse('thread-view', kwargs={'pk': self.pk})
class Post(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
thread = models.ForeignKey(Thread, on_delete=models.CASCADE)
title = models.CharField(max_length=300)
content = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return str(self.title)
def get_absolute_url(self):
return reverse('post-view', kwargs={'pk': self.pk})
views.py:
def homeView(request):
context = {
'threads': Thread.objects.all().order_by('-created_at'),
'posts': Post.objects.all().order_by('-created_at')
}
return render(request, 'forum/home.html', context)
class ThreadCreateView(CreateView):
model = Thread
fields = ['title', 'description']
def form_valid(self, form):
form.instance.user = self.request.user
return super().form_valid(form)
class PostCreateView(CreateView):
model = Post
fields = ['title', 'content'] # Right now I also have to add in 'thread' as a field but I don't want that to be the case
def form_valid(self, form):
form.instance.user = self.request.user
return super().form_valid(form)
urls.py:
path('', homeView, name='forum-home'),
path('create-thread/', ThreadCreateView.as_view(), name='create-thread'),
path('create-post/', PostCreateView.as_view(), name='create-post'),
home.html:
{% for thread in threads %}
<div class="border-bottom pb-2">
<h2><a href="{% url 'thread-view' thread.pk %}">{{ thread.title }}</a></h2>
<p>{{ thread.description }}</p>
<p>{{ thread.created_at|naturaltime }}</p>
<p>{{ thread.user }}</p>
<a href="#" class="btn btn-primary">Add a post to this thread</a>
{% for post in posts %}
{% if post.thread == thread %}
<div class="border p-2 m-3">
<h3><a href="{% url 'post-view' post.pk %}">{{ post.title }}</a></h3>
<p>{{ post.content }}</p>
<p>{{ thread.created_at|naturaltime }}</p>
<p>{{ thread.user }}</p>
</div>
{% endif %}
{% endfor %}
</div>
{% endfor %}
post_form.html:
<form method="POST">
{% csrf_token %}
<fieldset>
<legend>Create Post</legend>
{{ form }}
</fieldset>
<button type="submit" class="btn btn-primary">ADD</button>
</form>
Любые советы были бы замечательными. Спасибо!
Я бы рекомендовал не заводить отдельный вид / url для создания сообщения и просто написать специальный детальный вид и шаблон для отдельных тем. В шаблоне добавьте форму для отправки сообщений. Вы можете создать пользовательскую форму Post ModelForm, которая принимает вводимые данные и проверяет их.
Это может быть проще сделать с помощью представления на основе функций, но вам придется проверять наличие request.method == POST
и вручную сохранять экземпляр. Если у кого-то есть более чистое решение для представления на основе класса, я весь внимание.
# forms.py
class PostForm(forms.ModelForm):
"""
Form for processing post submissions.
"""
content = forms.CharField(widget=forms.Textarea, label='')
class Meta:
model = Post
fields = ['content']
# views.py
from .forms import PostForm
def topic_posts(request, *args, **kwargs):
# Put queries and logic for listing posts here
# Get thread from url params
thread = Thread.objects.get(id=kwargs['thread_id'])
redirect_uri = # build redirect back to thread
# Custom model form
pform = PostForm(request.POST or None)
# Save post instance on POST request
if request.method == 'POST' and pform.is_valid() and request.user.is_authenticated:
pinstance = pform.save(commit=False)
pinstance.author = request.user
pinstance.thread = thread
pinstance.save()
return HttpResponseRedirect(redirect_uri)