pk of an object in a CreateView with views based on Django classes

0

Cordial greeting.

I am in a table with users and when clicking I need to take the pk of the selected user to a form where a book will be created, so that this book is related to the user.

How can I do this process or how does it work?

models.py

class Usuario(models.Model):
  Nombre = models.CharField(max_length=100)
  Direccion = models.CharField(max_length=100)

  def __str__(self):
    return self.Nombre


class Libros(models.Model): 
   Nombre_Libro = models.CharField(max_length=30) 
   Guia = models.CharField(max_length=30)  
   IDUsuario  = models.ForeignKey(Usuario, null=True, blank=False, 
   on_delete=models.CASCADE)

   def __str__(self):
     return self.Nombre_Libro

forms.py

class LibrosForm(forms.ModelForm):

class Meta:
    model = Libros
    fields = ["Nombre_Libro", "Guia"]

    def __init__(self, *args, **kwargs):
       super(LibrosForm, self).__init__(*args, **kwargs)
          for field in iter(self.fields):
             self.fields[field].widget.attrs.update({
               'class': 'form-control',
               'placeholder':field
            })

views.py

class CrearLibros(CreateView):
  template_name = 'libros.html'
  form_class = LibrosForm
  success_url = reverse_lazy('libros')

====== UPDATE ======

So I'm urls.py

url(r'^listado_usuarios/$',ListadoUsuarios.as_view(), name="listado_usuarios"),
url(r'^crear_libros/(?P<usuario>.+)$',CrearLibros.as_view(), name="crear_libros")

views.py

class CrearLibros(CreateView):
template_name = 'libros.html'
form_class = LibrosForm
success_url = reverse_lazy('libros')

def get(self, request, *args, **kwargs):
    # Esto intenta obtener el valor de usuario, sino devuelve None
    id_usuario = request.GET.get('usuario')
    if id_usuario:
        # Intentamos recuperar ese usario desde la DB 
        usuario = Usuario.objects.get(id=id_usuario)
        # Ese get puede fallar, deberías capturar la excepción
        # Inicializamos el form con ese usuario ya cargado
        form = self.form_class(initial={'usuario': usuario})
    else:
        # Si no especificaron usuario en el request
        # mostramos el form vacio
        form = self.form_class()
    return render(request, self.template_name, {'form': form})

url that reaches books.html

http://127.0.0.1:8000/crear_libros/1

libros.html

<div class="modal-dialog modal-lg">
    <div class="modal-content">

                    <div class="modal-header">
            <button type="button" class="close" data-dismiss="modal">x</button>
            <h3>Libros</h3>
        </div>
        <div class="modal-body">

                        <h3>Ingresar Libro</h3>

                        <form role="form" action="" method="post">{% csrf_token %}

                                <div class="form-group">
                                <label>Libros</label>

                                    {{ form.as_p }}

                                </div>         


                                <button type="submit" class="btn btn-primary">Guardar</button>
                                <button type="reset" class="btn btn-default">Reset </button>

                            </form>             

                    </div>

            </form>
    </div>

The problem is that when I send the form of libros.html does not capture the id of the user who is going to create the book, then the book is left without a creator.

I am sending the user id but when I created the book I did not give how to capture it to relate the book with the user.

The action of the form is empty because if I send it to create_books it asks for a pk and I do not know how to put it.

I come from php, normally this is put in an input type hidden, but here no idea.

Thanks for the help !!!

    
asked by Vacanito 26.01.2018 в 23:42
source

2 answers

0

For that you should pass the user as a parameter in the URL of the link, for example:

/crear_libro/?usuario=<id_usuario>

Then you should modify your view a bit, to give it a different behavior to the GET method. Something more or less like this:

class CrearLibros(CreateView):
    template_name = 'libros.html'
    form_class = LibrosForm
    success_url = reverse_lazy('libros')

    def get(self, request, *args, **kwargs):
        # Esto intenta obtener el valor de usuario, sino devuelve None
        id_usuario = request.GET.get('usuario')
        if id_usuario:
            # Intentamos recuperar ese usario desde la DB 
            usuario = Usuario.objects.get(id=id_usuario)
            # Ese get puede fallar, deberías capturar la excepción
            # Inicializamos el form con ese usuario ya cargado
            form = self.form_class(initial={'usuario': usuario})
        else:
            # Si no especificaron usuario en el request
            # mostramos el form vacio
            form = self.form_class()
        return render(request, self.template_name, {'form': form})
    
answered by 27.01.2018 в 01:20
0

you must understand that in django everything is written and what you should do is simply overwrite methods or in most cases this is how I will give you a very simple example of how to relate the creator using the Generic template which I see what are you using the example is for you to understand how django works and so you can adapt it to your code

** using generic templates and assuming you are sending the author's pk and the form well

from .models import LibrosForm
from django.views.generic import CreateView

class CrearLibros(CreateView):
    template_name = 'libros.html'
    form_class = LibrosForm
    success_url = '/libros/'

#Sobreescribimos el método y lo ajustamos para que antes de guardarlo en la base de datos django lo pueda relacionar
def form_valid(self,form):
    instance = form.save(commit=False) # este pequeño paso es la magia que necesitas
    instance.<tu_creador> = self.request.<tu_creador_que_viene_del_template> # ahora tu form ya tiene relacionado tu creador
    return super(CrearLibros, self).form_valid(form)

I hope it helps you to understand a little more and manage to find the final solution greetings

    
answered by 31.01.2018 в 16:38