Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Render Form ViewSet Django Rest Framework

I would like to do the following:

With my model

class User(models.Model):
   id = models.AutoField(primary_key=True)
   field1 = models.CharField(max_length=100)
   fk1 = models.ForeignKey(Group)
goes on

After this, I created my Serializer, which looks like:

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = UserSerializer
        fields = (...)

    ...

Lastly, I create my ViewSet, which should look like this:

class UserViewSet(viewsets.ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer

but now, how would I be able to create a viewSet and, for example, generate a form with my class? My final idea is to be able to do something like:

def my_view(request):
   my_form = UserViewSet.as_view({'get': 'list'}(request))
   # from here either to be able to use .render().content
   # or, inside the template, render with {% render_form my_form %}

Is this possible? Thank you

like image 569
Bobleujr Avatar asked Dec 15 '16 18:12

Bobleujr


People also ask

What is ViewSet in Django REST framework?

Django REST framework allows you to combine the logic for a set of related views in a single class, called a ViewSet . In other frameworks you may also find conceptually similar implementations named something like 'Resources' or 'Controllers'.

Should I use APIView or ViewSet?

APIView and ViewSet all have their right use cases. But most of the time, if you are only doing CRUD on resources, you can directly use ViewSets to respect the DRY principle. But if you are looking for more complex features, you can go low-level because after all, viewsets are also a subclass of APIView .


2 Answers

What you're suggesting is possible, but it doesn't usually make sense. Django Rest Framework is great for creating an API so that you can send and receive information to and from that api, maybe in JSON format.

Getting a form involves getting rendered HTML from the server. That's a better task for Django itself. You could use a CreateView to do what you're trying to:

def UserCreateView(CreateView):
    model = User
    form_class = "name_of_your_form.html"  # Or you could call the form 'user_create_form.html` and leave this line out.
    fields = [...]

Your form will then be available in your template, per the docs:

<form action="" method="post">{% csrf_token %}
    {{ form.as_p }}
    <input type="submit" value="Save" />
</form>
like image 69
YPCrumble Avatar answered Nov 08 '22 13:11

YPCrumble


As docs says:

Serializers may be rendered as forms by using the render_form template tag, and including the serializer instance as context to the template.

Next example will probably work for you. But how @YPCrumble sayed DRF goal is easy and fast build an API, not rendering forms

class UserDetail(APIView):
    renderer_classes = [TemplateHTMLRenderer]
    template_name = 'your_template.html'

    def get(self, request, pk):
        serializer = UserSerializer(profile)
        return Response({'serializer': serializer})

    def post(self, request, pk):
        user = get_object_or_404(User, pk=pk)
        serializer = UserSerializer(data=request.data)
        if not serializer.is_valid():
            return Response({'serializer': serializer})
        serializer.save()
        return redirect('some_url_name')  

template file:

{% load rest_framework %}
<html><body>

   <form action="{% url 'user_url' pk=user.pk %}" method="POST">
        {% csrf_token %}
        {% render_form serializer %}
        <input type="submit" value="Save">
    </form>

</body></html>

`DRF Docs link

like image 2
Ivan Semochkin Avatar answered Nov 08 '22 11:11

Ivan Semochkin