Save comment.id to another object - django

I want to save in my database the comment id which has been commented. For that I have two models: Comentario and Pregunta. Look below:
models.py
class Comentario (models.Model):
titulo = models.CharField(max_length=50)
texto = models.CharField(max_length=200)
autor = models.ForeignKey (Perfil, null=True, blank=True, on_delete=models.CASCADE)
fecha_publicacion = models.DateTimeField(auto_now_add=True)
tag = models.ManyToManyField(Tags, blank=True)
def __str__(self):
return (self.titulo)
class Pregunta (models.Model):
descripcion = models.CharField(max_length=150)
autor = models.ForeignKey (Perfil, null=True, blank=True, on_delete=models.CASCADE)
fecha_pregunta = models.DateTimeField(auto_now_add=True)
comentario_preguntado = models.ForeignKey(Comentario, null=True, blank=True, related_name="pregunta_set")
def __str__(self):
return (self.descripcion)
When a comment is commented I want to save the 'comentario' id as 'comentario_preguntado' id. For that I have created the next view:
views.py
def ComentarioListar2 (request):
aa=Puesto.objects.filter(nombre_puesto=request.user.nom_puesto).values_list('etiquetas')
bb=Tags.objects.filter(id__in=aa)
objects=Comentario.objects.filter(tag__in=bb).exclude(autor__id=request.user.id)
form = preguntaform(request.POST or None)
if request.method == 'POST' and form.is_valid():
form.instance.autor = request.user
form.instance.comentario_preguntado=request.comentario.id
form.save()
return render(request, 'home/comentario_listar.html', {'objects': objects, 'form': form})
urls.py
urlpatterns = [
url(r'^listar2$', views.ComentarioListar2, name="listar2"),
]
But I obtain this error "ComentarioListar2() missing 1 required positional argument: 'Comentario_id'"
I do not know how to save in the comentario_preguntado id the id of the comment it is commented (comentario_id).
thank you for your help

Your URL needs to be declared so that the primary key of the model instance can be referred to from the view.
It should be like this:
url(r'^listar2/(?P<Comentario_id>[0-9]+)/$', views.ComentarioListar2, name="listar2"),
So, an example of the URL would be /listar2/101/. Where 101 is the ID of your Comentario model instance.
Then, you can access it in the view with the function you have defined:
def ComentarioListar2 (request, Comentario_id):
^^^^^^^

Related

Passing parent object into CreateView for a child object

I'm creating a dashboard to edit a tour app.
Per tour I have a child record in which I define steps. The 2 models look like this:
models.py
class Tour(models.Model):
tour_id = models.CharField(primary_key=True,unique=True, max_length=10)
country = models.ForeignKey(Countries, models.DO_NOTHING, db_column='country')
language = models.ForeignKey(Language, models.DO_NOTHING, db_column='language')
lastupddtm = models.DateTimeField(default=timezone.now)
productid = models.CharField(max_length=50)
title = models.CharField(max_length=50)
description = models.CharField(max_length=100)
descrlong = models.CharField(max_length=1000)
live = models.CharField(max_length=1)
image = models.ImageField(upload_to=upload_tour_image, storage=OverwriteStorage(), blank=True, null=True)
class Meta:
db_table = 'tour'
verbose_name_plural = "tour"
def get_language_flag(self):
return self.language.flag.url
def __str__(self):
return str(self.tour_id) + ' - ' + str(self.title) + ' - ' + str(self.description)
class Toursteps(models.Model):
# tour_id = models.OneToOneField(Tour, models.DO_NOTHING, db_column='tour_id')
tour = models.ForeignKey(Tour, related_name='toursteps', on_delete=models.CASCADE)
step = models.IntegerField(unique=True)
title = models.CharField(max_length=50)
description = models.CharField(max_length=100)
descrlong = models.CharField(max_length=1000)
audiotext = models.TextField()
latitude = models.FloatField()
longitude = models.FloatField()
radius = models.FloatField()
image = models.ImageField(upload_to=upload_tour_step_image, blank=True, null=True)
class Meta:
db_table = 'tourSteps'
verbose_name_plural = "tourSteps"
def __str__(self):
return str(self.tour) + "|" + str(self.step)
After I created a Tour, I go to a detail page. From there I can click a link to add a step for this tour.
This is where the problem is. I pass the tour_id as a variable into the url, but I can't find a way to pick it up in the CreateView of the step.
urls.py
urlpatterns = [
path('tour/<str:pk>/detail', views.TourDetailView.as_view(), name='tour_detail'),
path('tour/<str:pk>/edit', views.UpdateTourView.as_view(), name='tour_edit'),
path('tour/<str:pk>/remove', views.DeleteTourView.as_view(), name='tour_remove'),
path('tour/<str:tour_id>/step/new', views.CreateTourStepView.as_view(), name='tour_step_new')
]
Tour detail view
<p><span class="glyphicon glyphicon-plus"></span></p>
views.py
class CreateTourStepView(LoginRequiredMixin,CreateView):
login_url = '/login/'
redirect_field_name = 'tour_admin/tour_list.html'
success_url = '/'
form_class = TourStepForm
model = Toursteps
def get_context_data(self, **kwargs):
context = super(CreateTourStepView, self).get_context_data(**kwargs)
print(context['tour_id'])
return context
forms.py
class TourStepForm(forms.ModelForm):
class Meta():
model = Toursteps
#fields = '__all__'
exclude = ('tour',)
def form_valid(self, form):
if form.is_valid():
form.instance.tour_id = self.request.GET("tour_id")
form.instance.save()
return HttpResponseRedirect(self.get_success_url())
def get_success_url(self):
return reverse('tour_detail', kwargs={'pk':form.instance.tour_id})
First, your form_valid() and get_success_url() methods belong in your view, not in your form.
Second, the tour_id is passed to the view's kwargs, it's not a query parameter, hence not in self.request.GET. You can find it in self.kwargs.
Third, you need to actually fetch the Tour from your database, not just assign the tour_id. I could post to any tour_id if I wanted and there's no guarantee the tour_id belongs to an actual Tour object. Return a 404 if the tour doesn't exist. And if it exists, assign it to the tour step.
Finally, you should not assign to and save form.instance. You should get the instance using step = form.save(commit=False), then assign to step and save step.

How to dynamically filter a view by ModelChoiceField selection

I have created a template that renders a dropdown list of students.
I want to filter a query set on another view to show schedule info for just the student that was selected.
perm_id in student_list is primary key and perm in StudentSchedule is foreign key.
Here are snippets of my models.py, forms.py and views.py
models.py
class StudentList(models.Model):
student_name = models.CharField(max_length=45, blank=True, null=True)
perm_id = models.IntegerField(primary_key=True)
class StudentSchedule(models.Model):
perm = models.ForeignKey(StudentList, on_delete=models.CASCADE)
begin_period = models.CharField(max_length=45, blank=True, null=True)
section_id = models.CharField(max_length=45, blank=True, null=True)
course_title = models.CharField(max_length=45, blank=True, null=True)
last_name1 = models.CharField(max_length=45, blank=True, null=True)
forms.py
class StudentForm(forms.Form):
Student = forms.ModelChoiceField(queryset=StudentList.objects.all()
.order_by('student_name'))
views.py
class ScheduleView(View):
form_class = ScheduleForm
template_name = 'learning_logs/student_schedule.html'
def get(self, request):
form = self.form_class(initial={})
data = StudentSchedule.objects.filter()
return render(request, self.template_name, {'form': form, 'data':
data})
I can do the following and get student with id # 123456
data = StudentSchedule.objects.filter(perm=123456)
But, I want Django to use the perm_id from the student selected from StudentList
My urls are as follows:
# Page for selecting a student from drop down list
path('select_student/', views.StudentView.as_view(), name='select_student'),
# Page for displaying student schedule
path('student_schedule/<int:pk>/$', views.ScheduleView.as_view(),
name='student_schedule'),
Say your path is like
urlpatterns = [
path('students/<int:pk>/$', views.ScheduleView.as_view(), name='student-detail'),
...
]
Then you will get a additional argument in your get method and you can access that as
class ScheduleView(View):
form_class = ScheduleForm
template_name = 'learning_logs/student_schedule.html'
def get(self, request, pk):
form = self.form_class(initial={})
data = StudentSchedule.objects.filter(perm=pk)
return render(request, self.template_name, {'form': form, 'data':
data})
Edit
And also in your student_schedule.html you need to perm.id to access this url as
{% url ... perm.id%}

how can I increase the value of my article in another model view for example in django

So here, I would like the quantity existing of my Article model to increase when saving the Purchase model,
Here is my code in views.py that does not work!
I am still a beginner in Django. thank you in advance
example:
quantity of article in stock: 20
quantity purchased during a purchase: 5
so in the end in the database I would like to have 25 in the item warren in stock!
sorry for my english, i use google translator
def achat_form_view(request):
if (request.method == 'POST'):
form = AchatForm(request.POST,error_class=ParagraphErrorList)
if form.is_valid():
Article.quantite = Article.quantite + Achat.quantite_a
form.save(commit=True)
return redirect('manapoitra_achat')
else:
form = AchatForm()
return render(request, 'achatH.html', {'form': form})
models.py :
class Achat(models.Model):
id_article_a = models.ForeignKey(Article, on_delete=models.CASCADE)
id_fournisseur_a = models.ForeignKey(Fournisseur, on_delete=models.CASCADE)
quantite_a = models.PositiveIntegerField(max_length=4, verbose_name="Quantité(s)")
date_a = models.DateTimeField(auto_now_add=True, verbose_name="Date de création")
date_save_tara_a = models.DateField(blank=True, null=True)
def __unicode__(self):
return self.pk+' achat'
class Article(models.Model):
photo = models.FileField()
nom = models.CharField(max_length=60, verbose_name="Produit")
type = models.ForeignKey(Type, verbose_name="Type", on_delete=models.CASCADE)
categorie = models.ForeignKey(Categorie, verbose_name="Catégorie", on_delete=models.CASCADE)
prix_de_vente = models.CharField(max_length=8, verbose_name="Prix de vente")
prix_d_achat = models.CharField(max_length=8, verbose_name="Prix d'achat")
quantite = models.PositiveIntegerField(max_length=4, verbose_name="Quantité(s)")
date_a = models.DateTimeField(auto_now_add=True, verbose_name="Date de création")
date_de_perim = models.DateField(blank=True, null=True, verbose_name="Perimé(e) le")
def __str__(self):
return self.nom
The problem with your code is that Achat and Article refer to the entire class, not any specific instance. What you want to do is take the Achat created by your form, and increase the quantity of the specific Article chosen in that form. You can do this via the return value of form.save(), which is an instance of Achat.
if form.is_valid():
achat = form.save()
article = achat.id_article_a
article.quantite += achat.quantite_a
article.save()
return redirect('manapoitra_achat')
(Note, your field naming convention is very strange; there's no need to suffix with _a, but more importantly you should not name ForeignKey fields with an id_ prefix; the Django ForeignKey is not an ID, but gives you access directly to the related object. So for example id_article_a should be just article.)

Inline Custom Form in Django

I am trying to create a system to add applications (named Candidatura in models.py) to a database and, in each application, the user can add as many experiences (named CandidaturaExp in models.py) as they wish (one to many relation).
I already have forms.py and views.py working for the application but I have no idea how to do it so a the user can insert experiences. I also have no idea how to create a "PLUS" button in my template to add the experience form since I am not an expert in Java Script.
So, I have the following:
models.py
class Candidatura(models.Model):
## IDENTIFICACAO E CONTACTO
nome=models.CharField(max_length=200, verbose_name='Nome Completo')
nacionalidade=models.CharField(max_length=200, verbose_name='Nacionalidade')
data_nascimento=models.DateField(verbose_name='Data de Nascimento')
residencia=models.CharField(max_length=200, verbose_name='Residência')
localidade=models.CharField(max_length=200, verbose_name='Localidade')
cod_postal=models.CharField(max_length=10, verbose_name='Código Postal')
email=models.EmailField(max_length=254, verbose_name='Email')
telefone=models.IntegerField(verbose_name='Telefone')
## HABILITACAO E CONHECIMENTOS
nivel_academico=models.CharField(max_length=200, verbose_name='Nível Académico')
ano_conclusao=models.CharField(max_length=4, verbose_name='Ano de Conclusão')
curso=models.CharField(max_length=200, verbose_name='Curso')
instituicao=models.CharField(max_length=200, verbose_name='Instituição')
outras_hab=models.CharField(max_length=255, null=True, blank=True, verbose_name='Outras Habilitações')
conhec_tec=models.CharField(max_length=255, null=True, blank=True, verbose_name='Conhecimentos Técnicos')
## DOCUMENTOS ANEXOS
cv=models.FileField(upload_to=None, max_length=100, verbose_name='Curriculum Vitae', null=True, blank=True)
data_criado=models.DateTimeField(default=timezone.now, editable=False, verbose_name='Data de criação')
def __unicode__(self):
return self.nome
## EXPERIENCIA PROFISSIONAL
class CandidaturaExp(models.Model):
candidatura = models.ForeignKey(Candidatura)
experiencia=models.BooleanField(verbose_name='Experiência Profissional')
ano_admissao=models.CharField(max_length=4, null=True, blank=True, verbose_name='Ano de Admissão')
ano_saida=models.CharField(max_length=4,null=True, blank=True, verbose_name='Ano de Saída')
empresa=models.CharField(null=True, blank=True, max_length=200, verbose_name='Empresa')
funcao=models.CharField(null=True, blank=True, max_length=255, verbose_name='Função Desempenhada')
def __unicode__(self):
return self.candidatura
class CandidaturaForm(ModelForm):
class Meta:
model = Candidatura
fields = '__all__'
class CandidaturaExpForm(ModelForm):
class Meta:
model = CandidaturaExp
fields = '__all__'
forms.py
class NovaCandidatura(forms.ModelForm):
class Meta:
model = Candidatura
fields = ('__all__')
class NovaCandidaturaExp(forms.ModelForm):
class Meta:
model = CandidaturaExp
fields = '__all__'
views.py
def inicio(request):
return render_to_response('indexDB.html', locals(), context_instance=RequestContext(request))
#login_required
def listing(request):
table = CandidaturaTable(Candidatura.objects.all())
return render(request, "listDB.html", {'table': table})
#login_required
def newform(request, template_name="NovaCandidatura.html"):
if request.method == 'POST':
form = NovaCandidatura(request.POST, request.FILES)
if form.is_valid():
form.save()
url = urlresolvers.reverse('change_success')
return HttpResponseRedirect(url)
else:
form = NovaCandidatura()
page_title = ('Update user data')
return render_to_response(template_name, locals(),
context_instance=RequestContext(request))

How do I map one models objects to another models objects in a view

I have a bunch of message records that I would like to assign to different taskboxes.
#models.py
class TaskBox(models.Model):
name = models.CharField(max_length=64, blank=False)
def __str__(self):
return u'%s' % (self.name)
class Admin:
pass
class InboxEntry(models.Model):
job_number = models.CharField(max_length=14, unique=False, blank=False, null=False)
job_name = models.CharField(max_length=64, unique=False, blank=False, null=False)
request = models.CharField(max_length=64, choices=PRINT_CHOICES, blank=True, null=True)
date_due = models.DateTimeField(("Due"),auto_now=False)
note = models.TextField(max_length=1000, unique=False, blank=True, null=True)
assigned_by = models.ForeignKey(UserProfile, blank=False, null=False)
box = models.ForeignKey(TaskBox)
assigned_to = models.ManyToManyField(UserProfile, related_name='name', blank=True)
status = models.CharField(max_length=30, choices=STATUS_CHOICES, default="Awaiting Action")
def __str__(self):
return u'%s %s' % (self.job_number, self.job_name)
class Admin:
pass
class Meta:
ordering = ['status']
The idea is for the template to have some generic tags like {{ for taskbox in taskboxes }} to create a separate div for each taskbox that will hold a table for that box's records. My problem is constructing the view function...
#views.py
def display_prdInboxEntry(request, id):
if request.method == 'POST':
form = PrdInboxForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect('taskmanager/display/'+ id +'/')
else:
form = PrdInboxForm(request.POST)
return HttpResponseRedirect('taskmanager/display/'+ id +'/')
else:
form = PrdInboxForm()
user = request.user
**taskboxes = TaskBox.objects.all()
records_1 = InboxEntry.objects.filter(taskboxes[id]=1)
records_2 = InboxEntry.objects.filter(taskboxes[id]=2)
records_3 = InboxEntry.objects.filter(taskboxes[id]=3)
..... **
return render_to_response('taskmanager/taskmanager_view.html', {'form': form, 'taskboxes': taskboxes, 'records_1' : records_1, 'records_2' : records_2, 'records_3' : records_3, 'user': user}, context_instance=RequestContext(request))
The InboxEntry model has a field called "box" that's just a reference to the TaskBox model. I need a way to map say... TaskBox id 1 with all of the InboxEntry objects with "box = 1" so that I can populate the templates appropriately. Can I construct the function to accommodate this, or am I going about it the wrong way entirely?
It sounds like you're looking for the automatically-generated attribute for reverse lookups. You can get a QuerySet of all InboxEntries associated with a TaskBox like this:
TaskBox.objects.filter(id=1).inboxentry_set.all()
See the documentation on related objects.