Какой из них удобнее создавать форму django, CreateView или forms.ModelForm

Я очень новичок в джанго. Я хочу создать форму публикации, которая может иметь заголовок, контент, загрузку изображения/файла и т. д. Я очень запутался с концепцией моделей и createview. Я пробовал это:

блог/view.py:

class PostCreateView(LoginRequiredMixin, CreateView):

    model = Post
    fields = ['title', 'content', 'imagefile']
    success_url = '/blog/home/'
    # template_name = 'blog/post_form.html'

    def __init__(self, *args, **kwargs):
        super(PostCreateView, self).__init__(**kwargs) # Call to ModelForm constructor

    def form_valid(self, form):
        form.instance.author = self.request.user
        form.save()
        return super().form_valid(form)

блог/шаблоны/блог/post_form.html:

{% extends "blog/base.html" %}
{% load crispy_forms_tags %}
{% block content %}
    <div class="content-section">
        <form method="POST">
            {% csrf_token %}
            <fieldset class="form-group">
                <legend class="border-bottom mb-4">Post::</legend>
                {{ form|crispy }}
                <img src='{{ post.imagefile.url }}'>
                <br><br>
            </fieldset>
            <div class="form-group">
                <button class="btn btn-outline-info" type="submit">Update</button>
            </div>
        </form>
    </div>
{% endblock content %}

блог/urls.py:

from django.urls import path
from .views import (
    PostCreateView,
)
urlpatterns = [
        path('blog/post/new/', PostCreateView.as_view(), name='post-create')
]

блог/models.py

class Post(models.Model):
    title = models.CharField(max_length=100)
    content = models.TextField()
    date_posted = models.DateTimeField(default=timezone.now)

    # image = models.ImageField(default='default_post.jpg', upload_to='postimages')
    imagefile = models.FileField(upload_to='postimages', null=True, verbose_name="")


    # if user is deleted the idea should be deleted as
    author = models.ForeignKey(User, on_delete=models.CASCADE)

def __str__(self):
    # return self.title
    return self.title + ": " + str(self.imagefile)

def get_absolute_url(self):
    return reverse('post-detail', kwargs={'pk': self.pk})

Мой вопрос: все, что я хочу, это создать своего рода форму для создания нового сообщения с названием, содержанием, кнопкой загрузки и кнопку отправить. Однако я не знаю, можно ли настроить CreateView даже для добавления дополнительных элементов или форм. Следует ли использовать формы модели?


person J2015    schedule 11.06.2020    source источник


Ответы (1)


Вы хотите, чтобы ваше представление было в views.py, а ваша форма — в forms.py. Вам понадобятся оба, а не один или другой.

Что-то типа:

class CreateXYZView(CreateView):
    template_name = "blog/post_form.html"
     model = Post
     form_class = postform



...do view stuff
    def post(self, request, *args, **kwargs):

Также есть файл forms.py

class postform(forms.ModelForm):
   class Meta:
       model = Post
       widgets = {}
       exclude = ['fieldname']

Похоже, вы используете модель с именем Post, что является хорошей идеей. Объявляя postform как forms.ModelForm, он извлечет поля вашей модели в форму IE из класса Post, он извлечет заголовок, контент, поле изображения и т. д., если поле специально не добавлено в параметр exclude. Это полезно для параметров вашей модели, таких как автоматические поля created_by или post_date, где пользователь не должен заполнять их вручную. Добавьте их в список исключений, чтобы они не отображались в форме.

Вы также можете вручную добавить поля формы в свой шаблон после {{form|crispy}}, но я бы этого не делал, так как это создает больше работы при обработке данных.

Если вы заполняете форму, которая не привязана к модели, вы также можете использовать forms.Form:

class SupportTicket(forms.Form):
    title = forms.CharField(label="Titlte", max_length=250, widget=forms.TextInput(...)
    content = forms....

НАПРИМЕР. используйте это, когда информация передавалась непосредственно в GitLab, а не сохранялась локально в модели для последующего использования.

person Chad    schedule 11.06.2020
comment
Спасибо за ваш ответ. Но я немного сбит с толку, так как вы предложили создать форму как постформу и ни разу не упомянули, где я должен ее использовать! В моем определении функции представления, называемой post_created(), и в той, которая импортирует PostCreateView(). В URL-адресах я вызываю post_created. Однако не знаю, что мне делать с постформой! - person J2015; 13.06.2020
comment
Здравствуйте, у вас уже есть форма в вашем шаблоне с {{ form|crispy }}. Это заставит вашу форму появиться. Когда вы нажмете «Отправить», он позаботится о действии, которое обычно представляет собой действие post. проверьте docs.djangoproject.com/en/3.0/topics/forms в разделе «Вид», где указано def get_name, в частности, request.method == 'POST'. Когда вы отправляете форму, она должна запускать действие публикации, которое затем подхватывается представлением. Затем вы делаете свою логику, т.е. форма.is_valid(). Если вам нужна конкретная проверка, например, дата публикации должна быть ›= сегодня, тогда поместите is_valid() в свой form.py - person Chad; 15.06.2020