Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

301
Views
Django create post

I am trying to create a new post to a forum, and it does work, i am also printing if the form is valid, but when i go to check after the post is not posted. In the admin page, the post is there, approved, but missing the tags and category fields. They was added when the post was created, if not i get an error. But I have to manually add them in the admin page to get the post posted to the forum.

Here is my Post in models

class Post(models.Model):
    title = models.CharField(max_length=400)
    slug = models.SlugField(max_length=400, unique=True, blank=True)
    user = models.ForeignKey(Author, on_delete=models.CASCADE)
    content = HTMLField()
    categories = models.ManyToManyField(Category)
    date = models.DateTimeField(auto_now_add=True)
    approved = models.BooleanField(default=True)
    tags = TaggableManager()
    comments = models.ManyToManyField(Comment, blank=True)
    # closed = models.BooleanField(default=False)
    # state = models.CharField(max_length=40, default="zero")

    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = slugify(self.title)
        super(Post, self).save(*args, **kwargs)

    def __str__(self):
        return self.title

Here is my views.py

@login_required
def create_post(request):
    context = {}
    form = PostForm(request.POST or None)
    if request.method == "POST":
        if form.is_valid():
            print("\n\n form is valid")
            author = Author.objects.get(user=request.user)
            new_post = form.save(commit=False)
            new_post.user = author
            new_post.save()

            return redirect('forums')
        
    context.update({
            'form': form,
            'title': 'Create New Post'
    })
    return render(request, 'forums/create_post.html', context)

The html is just very simple, to test.

<form method="POST">
                            {% csrf_token %}    
                            {{form|crispy}}
                            <!-- Submit Post -->
                            <input type="submit" value="Save">
                        </form>

Please any help would be much appreciated

over 4 years ago · Santiago Trujillo
2 answers
Answer question

0

The line, new_post = form.save(commit=False) will not save the many to many relationship according to the docs. The workaround

new_post = form.save(commit=False)
new_post.user = author
new_post.save()
form.save_m2m()

Excerpt from the docs

Another side effect of using commit=False is seen when your model has a many-to-many relation with another model. If your model has a many-to-many relation and you specify commit=False when you save a form, Django cannot immediately save the form data for the many-to-many relation. This is because it isn’t possible to save many-to-many data for an instance until the instance exists in the database.

To work around this problem, every time you save a form using commit=False, Django adds a save_m2m() method to your ModelForm subclass. After you’ve manually saved the instance produced by the form, you can invoke save_m2m() to save the many-to-many form data.

I don't think this solves everything, but give it a try.

over 4 years ago · Santiago Trujillo Report

0

The reason a ModelForm can not save the many-to-many relation when commit=False is because it does not create the Post at the database side, and hence has no primary key that can be used to add the many-to-many relations.

You can use .save_m2m() to save the many to many relations after you have saved the instance wrapped in the form, but perhaps a more elegant solution is to attach the request.user to the instance wrapped in the form, and then save the form, since then the form will save the many-to-many relations as well in the same function call, so:

from django.shortcuts import get_object_or_404

# …

if form.is_valid():
    form.instance.user = get_object_or_404(Author, user=request.user)
    form.save()

It might be worth renaming the .user field to .author instead, since now it hints that it is storing a User object, not an Author object.

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!