0

So I have a model Post with the following definition:

class Post(models.Model):
    post_body = models.TextField()
    user = models.ForeignKey(
        to=User,
        on_delete=models.CASCADE
    )
    published = models.BooleanField(
        default=False
    )
    schedule = models.DateTimeField(
        default=timezone.now
    )

I have created a form in HTML template allowing the user to select the posts he want to send to another website or social media account. Like so:

<form>
    <table class="table table-hover">
        <thead>
        <tr>
            <th scope="col">Select</th>
            <th scope="col">Post Body</th>
            <th scope="col">Published?</th>
            <th scope="col">Schedule (Editable)</th>
        </tr>
        </thead>
        <tbody>
        {% for post in posts %}
            <tr>
                <td>
                    <div class="form-group">
                        <input type="checkbox" value="{{ post.id }}">
                    </div>
                </td>
                <td>{{ post.post_body }}</td>
                <td>{{ post.published }}</td>
                <td>
                    <div class="form-group">
                        <input type="datetime-local" class="form-control" name="schedule" value="{{ post.schedule|date:"Y-m-d\TH:i" }}">
                    </div>
                </td>
            </tr>
        {% endfor %}
        </tbody>
    </table>
    <button class="btn btn-primary" type="submit">Post</button>
</form>

I want to create a Form in the forms.py in order to process this information (i.e. know which all posts were selected) and then perform further actions (calling other APIs in order to publish these to other sites), also since the field schedule is editable, I want to be able to save that as well. Please help as I cannot think of a possible form for this.

3 Answers 3

1
+50

One way to solve it is to use ModelMultipleChoiceField

Here is the structure I've used for similar scenarios:

class SelectPostsForm(forms.Form):
    posts = forms.ModelMultipleChoiceField(
        queryset=Post.objects.none(), widget=forms.CheckboxSelectMultiple)

    def __init__(self, filtered_post_queryset, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['posts'].queryset = filtered_post_queryset

    def get_posts(self):
        return self.cleaned_data.get('posts')


    # Example usage
    form = SelectPostsForm(Post.objects.all(), data=request.data)
    if form.is_valid():
       selected_posts = form.get_posts()
       # Process posts...

It will probably work directly with the html code you showed if you add name="posts" the the input.

The "filtered_post_queryset" you can provide via the view if you need to do this on a filtered/restricted queryset. Data will then be properly validated via form.is_valid() against the filtered queryset.

Sign up to request clarification or add additional context in comments.

Comments

1

If you want to handle multiple objects of the same type through forms, then you should try with formsets - https://docs.djangoproject.com/en/3.0/topics/forms/formsets/

There's a lot of other options, but I think that formset will cover your needs.

EDIT: Please take it as a guide only:

# forms.py


class PostForm(forms.ModelForm):
    is_selected = forms.BooleanField(default=False)

    class Meta:
        model = Post
        fields = ("is_selected", "other", "model" "fields")


PostFormSet = modelformset_factory(Post, form=PostForm)
# views.py

class PostView(generic.View):
    def get(self, request, *args, **kwargs):
        posts = Post.objects.all()  # get your Post queryset
        formset = PostFormSet(queryset=posts)
        # ...
        return response

    def post(self, request, *args, **kwargs):
        formset = PostFormSet(request.POST)
        for form in formset.forms:
            if form.is_valid() and form.cleaned_data.get("is_selected"):
                # here you can save your instance and/or write logic 
                # to process gathered information
        # ...
        return response  

2 Comments

Formsets allow me to add multiple posts of the model, O have used them before. Here if you see the html code, I want to select some of the posts and send them, then those need to be sent over by the api to some other website. Can you provide sample code?
That is one way to do it but I wanted something like Daniel's answer, thank you anyways
0

You want all your "posts" to render by "one form()" then manipulate the selected posts. Formsets are used for this in django. Although there are many types but any simple formset will get your work done.

Please visit django documentation for implementation: https://docs.djangoproject.com/en/3.0/topics/forms/formsets/

For quick and easy understanding visit this: https://www.geeksforgeeks.org/django-formsets/

1 Comment

Formsets allow me to add multiple posts of the model, O have used them before. Here if you see the html code, I want to select some of the posts and send them, then those need to be sent over by the api to some other website. Can you provide sample code?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.