Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
222 views
in Technique[技术] by (71.8m points)

django - How do I include my def clean_slug function into my views or template so that it will work and show "title alr exist"

Hi I have written a def clean(self) function in forms to make sure that if there was previously already a post with the same title, they will return a message saying that the title already exists and hence the form cannot be submitted.

Problem now:

When I enter a title that already exists and I try to create the post, all data previously input will be removed and I will be redirected to a fresh form. No errors were raised. What I want is for the error to be raised and shown to the user when I try to click on the create button so all data remains there and the user knows and can change the title before attempting the create the blog post again.

return cleaned_data in forms.py is not defined too...giving a nameerror

Guideline:

Note! There is NO slug field in my form. The slug is only for the url for each individual blogpost. But basically the slug consists of the title. Eg if my username is hello and my chief_title is bye, my slug will be hello-bye. Both the slug and the title has to be unique as you can see in the model, but there is no slug in the form.

models.py

class BlogPost(models.Model):
 chief_title                    = models.CharField(max_length=50, null=False, blank=False, unique=True)
 brief_description = models.TextField(max_length=300, null=False, blank=False)
 author                     = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
 slug                   = models.SlugField(blank=True, unique=True)

views.py

def create_blog_view(request):
    context = {}
    user = request.user
    if not user.is_authenticated:
        return redirect('must_authenticate')
    if request.method == 'POST':
        form = CreateBlogPostForm(request.POST or None, request.FILES or None)
    
        if form.is_valid():
            obj= form.save(commit = False)
            author = Account.objects.filter(email=user.email).first()
            obj.author = author
            obj.save()
            obj.members.add(request.user)
            context['success_message'] = "Updated"
            return redirect('HomeFeed:main')
        else:
            form = CreateBlogPostForm()
            context['form'] = form
    return render(request, "HomeFeed/create_blog.html", {})

forms.py

class CreateBlogPostForm(forms.ModelForm):
    class Meta:
        model = BlogPost
        fields = ['chief_title']

    def clean(self):
        chief_title = self.cleaned_data['chief_title']
        qs = BlogPost.objects.filter(chief_title=chief_title)
        if qs.exists():
            raise forms.ValidationError('Post already exists')
        return cleaned_data

html

  <form class="create-form" method="post" enctype="multipart/form-data">{% csrf_token %}

    {% if form.non_field_errors %}
   {{form.non_field_errors}}  
    {% endif %}

   <!-- chief_title -->
   <div class="form-group">
    <label for="id_title">Chief Title!</label>
    <input class="form-control" type="text" name="chief_title" id="id_title" placeholder="Title" required autofocus>
   </div>   {{form.chief_title.errors}}



   <button class="submit-button btn btn-lg btn-primary btn-block" type="submit">CREATE</button>

  </form>   
question from:https://stackoverflow.com/questions/65879639/how-do-i-include-my-def-clean-slug-function-into-my-views-or-template-so-that-it

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Well you can create a custom validator to check if the slug exists:

from django.core.exceptions import ValidationError

def validate_slug_exists(value):
    blog_post = BlogPost.objects.filter(slug=value)
    if blog_post.exists():
        raise ValidationError('The post with a given title already exists')

Then in your form add this validator to the fields validators list:

class CreateBlogPostForm(forms.ModelForm):
    chief_title = forms.CharField(validators = [validate_slug_exists])

UPDATE

You can also try using validate_unique() in your form class:

def validate_unique(self, exclude=None):
    qs = BlogPost.objects.all()

    if qs.filter(chief_title=self.chief_title).exists():
        raise ValidationError("Blog post with this title already exists")

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...