Единая форма для всего процесса или отдельная для каждого типа поста | django
Я пытаюсь сделать приложение наподобие reddit, где вы можете создавать посты для любого сервера, но вам разрешено размещать только изображение&видео/текст, но не оба. Но проблема в том, что я не знаю, должен ли я сделать одну ModelForm для всего процесса и скрывать или показывать fileField и textField с помощью Javascript, или сделать ModelForm для каждого типа поста и изменить форму, которая отображается с помощью Javascript
posts/forms.py:
class CreatePostTextForm(ModelForm):
class Meta:
model = Post
fields = ['title','video','image','text']
widgets ={'title':forms.TextInput({'placeholder':'تیتر'}),
'text':forms.Textarea({'placeholder':'متن'})}
posts/views.py
class CreatePostView(LoginRequiredMixin, View):
form_class = CreatePostTextForm
def dispatch(self, request, *args, **kwargs):
user = User.objects.get(id=kwargs['pk'])
if not user.id == request.user.id:
messages.error(request, 'شما نمیتوانید باپست ایجاد کنید')
return redirect('home:home')
return super().dispatch(request, *args, **kwargs)
def get(self, request, pk):
form = self.form_class()
return render(request, 'posts/create-post.html', {'form':form})
def post(self, request, pk):
form = self.form_class(request.POST, request.FILES)
if form.is_valid():
saved_form = form.save(commit=False)
saved_form.creator = request.user
saved_form.save()
messages.success(request, 'پست شما باموفقیت ایجاد شد')
return redirect('home:home')
return render(request, 'posts/create-post.html', {'form':form})
posts/create-post.html
<div class="create-post-form-wrapper col-8">
<div class="form-header">
<div class="form-types">
<button onclick="postType(0)">
<p>متن</p>
<img src="{% static 'posts/svgs/file.svg' %}" alt="" />
</button>
<button onclick="postType(1)">
<p>عکس</p>
<img src="{% static 'posts/svgs/image.svg' %}" alt="" />
</button>
<button onclick="postType(2)">
<p>فیلم</p>
<img src="{% static 'posts/svgs/video.svg' %}" alt="" />
</button>
<button onclick="postType(2)">
<p>لینک</p>
<img src="{% static 'posts/svgs/link.svg' %}" alt="" />
</button>
</div>
</div>
<div class="form-wrapper">
<form
class="post-form"
action=""
method="post"
enctype="multipart/form-data"
novalidate
>
{% csrf_token %}
<div class="form-body">
<div id="title-field">{{form.title}} {{ form.title.errors }}</div>
<div class="field">{{form.text}} {{ form.text.errors }}</div> //will change depending on postType() js function
<div class="field">{{form.video}} {{ form.video.errors }}</div> //will change depending on postType() js function
<div class="field">{{form.image}} {{ form.image.errors }}</div> //will change depending on postType() js function
</div>
</form>
<div class="form-footer">
<button id="submit" onclick="submit()">ارسال</button>
</div>
</div>
</div>
и вот форма, которая имеет кнопки для скрытия или отображения полей, которые включены в CreatePostForm:
С помощью jQuery вы можете динамически скрыть ввод текстового поля или, напротив, ввод изображения&видео. Или, например, вы можете проверить данные POST и убедиться, что отправлены оба варианта (изображение&видео/текст), после чего не обрабатывать форму, а вернуть сообщение об ошибке. Ваш код должен выглядеть следующим образом:
if request.POST.get('images&videos') and request.POST.get('text'):
... # return error message
Приведенный выше код не очень читабелен, так как я написал его приблизительно, чтобы показать вам, как это можно сделать, и надеюсь, что вы поняли мою мысль. Просто переделайте его под себя.
Конечно, этот метод не будет иметь той динамики, которую вы могли бы иметь с JS, но также решает проблему.
Я бы предпочел выбрать метод jQuery fadeOut() (https://api.jquery.com/fadeout/), но оба эти решения хороши.
Задавайте вопросы, если есть, я вам помогу