Home > front end >  DJANGO: forms dont show error to user (def post ListView)
DJANGO: forms dont show error to user (def post ListView)

Time:07-26

can you help me? I can't fix problem: my don't show error validation when I write not unique slug at form -> no error at form

I think problem at use def post() or return redirect after validations form. I try many different solutions but nothing helps.

Maybe you should use a non-standard way to report an error?

models.py

class ShortUrl(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name='Автор URL', null=True)
    url = models.CharField('Ссылка', max_length=200)
    slug = models.SlugField('Короткое имя ссылки', unique=True, max_length=20)

    def __str__(self):
        #return self.slug
        return f"Короткая ссылка: {self.user} >> {self.slug}"
    ​
    class Meta:
        verbose_name = 'Ссылка'
        verbose_name_plural = 'Ссылки

forms.py

class ShortURLForm(forms.ModelForm):
    slug = forms.SlugField(
        label='Название URL',
        required=True,
        widget=forms.TextInput(attrs={'placeholder': 'Укажите уникальный URL'})
    )
    
    url = forms.CharField(
        label='Ссылка',
        required=True,
        widget=forms.TextInput(attrs={'placeholder': 'Ссылка которую нужно сократить'})​
    )

    class Meta:
        model = ShortUrl
        fields = ['user', 'url', 'slug']
        widgets = {'user': forms.HiddenInput()}

views.py

class ShortURLPage(LoginRequiredMixin, ListView):
    model = ShortUrl
    template_name = 'main/shorts.html'
    context_object_name = 'shorts'
​
    def get_context_data(self, *, object_list=None, **kwargs):
        ctx = super(ShortURLPage, self).get_context_data(**kwargs)
        ctx['form'] = ShortURLForm()
        userurls = ShortUrl.objects.filter(user=self.request.user)
        ctx['shorts'] = userurls
        ctx['title'] = 'Добавление ссылок'
        return ctx
​
    def post(self, request, *args, **kwargs):
        post = request.POST.copy()
        post['user'] = request.user
        request.POST = post
        form = ShortURLForm(request.POST)
​
        if form.is_valid():
            slug = form.cleaned_data['slug']
            url = form.cleaned_data['url']
            form.save()
​
        return redirect('shorts')

shorts.html

                <form method="post" >
                    {% csrf_token %}
                    {{ form }}            
                    <button  type="submit">Создать ссылку</button>
                </form>

urls.py

urlpatterns = [
    path('', views.homepage, name='home'),
    path('about/', views.about, name='about'),
    path('shorts/', views.ShortURLPage.as_view(), name='shorts'),
    path('shorts/<str:slug>/', views.urlRedirect, name='redirect'),

]

CodePudding user response:

Ok, you're not so far away with accomplishing what you want. Generally your post method should look like this:

    def post(self, request, *args, **kwargs):
        post = request.POST.copy()
        post['user'] = request.user
        request.POST = post
        form = ShortURLForm(request.POST)
​
        if form.is_valid():
            slug = form.cleaned_data['slug']
            url = form.cleaned_data['url']
            form.save()
        else:
            context = {
                'form': form,
            }
            return render(
                request, 
                self.template_name, 
                context,
            )

        return redirect('shorts')

Then, you should write your shorts.html template like this:

<form method="post" >
        {% csrf_token %}
        {{ form.non_field_errors }}
        {{ form.errors }}
        {{ form }}            
        <button  type="submit">Создать ссылку</button>
</form>

Can you check if it works? I hope it will help.

  • Related