Adding users to the specific group in Django - python

I'm trying to add some users, in my Django project, to my created before group, but I know how to add to the specific group which I know the name and it's not dynamic. I would like that when I select a specific group, already add the next user. The problem is here:
g = Group.objects.get(name= 'New')
What should I do to replace this and indicate this group which I clicked?
views.py:
#login_required
def choose_group(request, pk):
if request.method == "POST":
cvs = get_object_or_404(Cv, pk=pk)
p = Person.objects.create(name=cvs.author)
g = Group.objects.get(name= 'New')
m = Membership.objects.create(person=p, group=g, leader=False)
return redirect( 'proj.views.cv_detail', pk=cvs.pk )
else:
cv = Cv.objects.filter(author = request.user)
cvs = get_object_or_404(Cv, pk=pk)
mem = Membership.objects.all()
context = {
'mem':mem,
'cvs':cvs,
'cv':cv
}
return render(request, 'choose_group.html', context)
models.py:
class Person(models.Model):
name = models.CharField(max_length=128)
def __str__(self): # __unicode__ on Python 2
return self.name
class Group(models.Model):
name = models.CharField(max_length=128)
members = models.ManyToManyField(Person, through='Membership')
def __str__(self): # __unicode__ on Python 2
return self.name
class Membership(models.Model):
person = models.ForeignKey(Person)
leader = models.BooleanField(default=False)
group = models.ForeignKey(Group)
choose_groups.html:
{% block profile %}
<div class="jumbotron">
<h3>Choose a group to add:</h3>
</div>
<ul>
{% for m in mem %}
<form method="POST" class="post-form" >{% csrf_token %}
<li><button type="submit" class="li1"> <b>{{ m.group }}</b></li>
</form>
{% endfor %}
</ul>
{% endblock %}

The main issue i see here is that you are not sending the group name m.group from your html.
to do so, you must add name and value to the button element in your html (and don't forget to close the button element)
<button type="submit" class="li1" name="group" value="{{m.group}}"> <b>{{ m.group }}</b></button>
Then, you can retrieve this group value in your views.py by using request.POST
g = Group.objects.get(name=request.POST['group'])

Related

Django forms with variable user entries

I want to create a django form that captures user entry such as name, address, age. For this type of information I can create a model such as
class GeneralUserInfo(models.Model):
firstname = models.CharField()
lastname = models.CharField()
address = models.CharField()
# etc....
However, I also want to capture maybe some information like their class schedule or family information.
class UserSchedule(models.Model):
course_number = model.IntegerField()
course_name = model.CharField()
# etc....
class FamilyInfo(models.Model):
family_member_type = models.CharField(choices = MEMBER_CHOICES) # mother, father, sibling
family_member_name = models.CharField() # jon doe
# etc....
where by each user, the number of courses and number of family members could vary.
I would like the form to look something like below
with a simple submit button to send things off to be saved.
My question is, how should I structure the form template considering there are multiple models?
The answer to the above question can take a couple of forms. I'll rewrite the example above to add more context.
Say there's a student, Ashley, with college course work (say she's taking 4 course) and with family (mom, pop, sis, bro). I'd like to capture all this information for Ashley. So I've written the following models.py
class Student(models.Model):
firstname = models.CharField()
lastname = models.CharField()
address = models.CharField()
# etc....
class Course(models.Model):
user = models.ForeignKey(GeneralUserInfo, on_delete = models.CASCADE)
course_number = model.IntegerField()
course_name = model.CharField()
# etc....
class Family(models.Model):
user = models.ForeignKey(GeneralUserInfo, on_delete = models.CASCADE)
family_member_type = models.CharField(choices = MEMBER_CHOICES) # mother, father, sibling
family_member_name = models.CharField() # jon doe
# etc....
Next, what is needed is to use inlineformset_factory inside your views.
You could potentially have two views in views.py. One that creates the student, and another that edits the information belonging to that student.
from django.shortcuts import render, redirect
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from .forms import StudentForm
from django.forms import inlineformset_factory
from .models import Student, Course, Family
#login_required
def createstudent(request):
context = {'studentform': StudentForm}
if request.method == "POST":
form = StudentForm(request.POST)
if form.is_valid():
instance = form.save(commit = False) # https://www.youtube.com/watch?v=2h57cqFRcqg
instance.user = request.user
instance.save()
messages.success(request, "Saved new contact!")
return redirect('home')
return render(request, 'mainapp/createstudent.html', context)
#login_required
def editview(request, id):
student = Student.objects.get(pk = id)
CourseFormSet = inlineformset_factory(Student, Course, fields = ('name', 'skill'), extra=5, max_num=5)
FamilyFormSet = inlineformset_factory(Student, Family, fields = ('name', 'skill'), extra=5, max_num=5)
if request.method == "POST":
courseformset = CourseFormSet(request.POST, instance = contact)
Familyform = FamilyFormSet(request.POST, instance = contact)
if courseformset.is_valid():
courseformset.save()
if Familyform.is_valid():
Familyform.save()
if courseformset.is_valid() or Familyform.is_valid():
messages.success(request, "Saved new information")
return redirect('editview', id=id)
courseformset = CourseFormSet(instance = contact)
Familyform = FamilyFormSet(instance = contact)
context = {'courseformset': courseformset, 'title': 'Edit View', 'Familyform': Familyform}
return render(request, 'mainapp/editview.html', context)
Then inside an edit view template, editview.html
{% extends "mainapp/base.html" %}
{% block content %}
<h1>{{ title }}</h1>
<br>
<h5>Edit the form below</h5>
<br>
<form method = "POST">
<br>
<h2>Courses</h2>
<br>
{% csrf_token %}
{{ courseformset.management_form }}
{% for form in courseformset %}
<article class="media content-section">
<div class="media-body">
{{ form.as_p }}
</div>
</article>
{% endfor %}
<br>
<h2>Family</h2>
<br>
{{ Familyform.management_form }}
{% for form in Familyform %}
<article class="media content-section">
<div class="media-body">
{{ form.as_p }}
</div>
</article>
{% endfor %}
<div class="form-group">
<button class="btn btn-outline-info" type="submit">Submit</button>
</div>
</form>
{% endblock content %}
This is just an example. However, for a whole project example, please see: https://github.com/Johnnyboycurtis/onlineforms-project/

how to display all the reviews for the particular product?

With the below code i am adding reviews for some particular product in the database and it is doing good but the problem is while displaying the reviews for the selected product.I get confused how can i display the all reviews of some product and which review done by which user at what time?
models.py
class Product(models.Model):
name = models.CharField(max_length=250)
description = models.TextField(blank=True)
featured = models.BooleanField(default=False)
def __str__(self):
return self.name
class Review(models.Model):
product = models.ForeignKey(Product, on_delete=models.CASCADE)
user = models.ForeignKey(User, on_delete=models.CASCADE)
review = models.TextField()
date = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.review
views.py
def detail(request,pk):
product = College.objects.get(pk=pk)
form = ReviewForm()
return render(request,'products/detail.html',{'product':product,'form':form})
#login_required(login_url='products:signin')
def review(request,pk):
if request.method == "POST":
form = ReviewForm(request.POST)
if form.is_valid():
review = form.save(commit=False)
review.product = Product.objects.get(pk=pk)
review.user = request.user
review.save()
messages.success(request, "Review saved")
return redirect('products:detail',pk)
else:
messages.error(request,'error in form')
return redirect('products:detail', pk)
detail.html
<h3>All reviews(total.no. of reviews?)</h3>
# Here i want to display all reviews and which is done by which user and at what time
<div class="col-lg-6 col-md-6 mb-6">
<form method="post" action="{% url 'products:review' product.pk %}">
{% csrf_token %}
{% form.as_p %}
<input type="submit" class="btn btn-success">
</form>
</div>
You can do it like this using reverse relation:
<h3>All reviews {{ product.review_set.count }}</h3>
{% for review in product.review_set.all %}
{{ review.review }}
{{ review.date }}
{% endfor %}

django action with intermediate page keyerror

I'm newbie in django and I'm doing my first educational project. I would like make an action with an intermediate page, but I receive :
KeyError at /admin/students/student/ 'action'
Scenario:
User selects from "Actions" listbox , action called :
u'Перемістити у групу'
Presses Go
New page should appears with the list of students and listbox to select a group.
please explain where is my error. My code is listed below:
class UpdateGroupForm(forms.Form):
group = forms.ModelChoiceField(queryset=Group.objects.all().order_by('title'), required=False)
def update_group(modeladmin,request,queryset):
if 'change_group' in request.POST:
form=UpdateGroupForm(request.POST)
if form.is_valid():
group=form.cleaned_data['group']
updated_group=queryset.update(student_group=group)
counter=queryset.count()
modeladmin.message_user(request,u"У %s студентів було змненно групу на %s")%(counter,group)
return
if not form:
form= UpdateGroupForm()
return (request,'/students/change_group.html',{'students':queryset,'form':form,'title':u'Зміна групи'})
update_group.short_description=u'Перемістити у групу'
class StudenAdmin(admin.ModelAdmin):
action_form = UpdateGroupForm
actions = [update_group]
list_display = ['last_name','first_name' ,'ticket','student_group']
list_display_links = ['last_name','first_name']
list_editable = ['student_group']
ordering = ['last_name']
list_filter = ['student_group']
list_per_page = 10
search_fields = ['last_name','first_name' ,'ticket','notes']
def get_view_on_site_url(self, obj):
return reverse ('students_edit',kwargs={'pk':obj.id})
code of my page:
{% extends "admin/base_site.html" %}
{% block content %}
<form action="" method="post">
{% csrf_token %}
{{ form }}
<p>Групу буде змінено у таких студентів:</p>
<ul>{{ students|unordered_list }}</ul>
<input type="hidden" name="action" value="update_group" />
<input type="submit" name="change_group" value="Зберігти" />
</form>
{% endblock %}
and here is code of my models:
class Student (models.Model):
"""Student Model"""
class Meta (object):
verbose_name=u"Студент"
verbose_name_plural=u"Студенти"
first_name=models.CharField(max_length=256,blank=False,verbose_name=u"Ім'я")
last_name=models.CharField(max_length=256,blank=False,verbose_name=u"Прізвище")
middle_name=models.CharField(max_length=256,blank=True,verbose_name=u"По-батькові")
birthday=models.DateField(blank=False,verbose_name=u"Дата народження",null=True)
photo=models.ImageField(blank=True,verbose_name=u"Фото",null=True)
ticket=models.CharField(max_length=256,blank=False,verbose_name=u"Білет")
student_group=models.ForeignKey('Group',verbose_name=u"Група",blank=False,null=True,on_delete=models.PROTECT)
notes=models.TextField(blank=True,verbose_name=u"Додаткові нотатки")
def __unicode__(self):
return u"%s %s" % (self.first_name,self.last_name)
# post_delete signal deletes student photo
post_delete.connect(remove_photo,Student)
class Group (models.Model):
"""Group Model"""
class Meta(object):
verbose_name=u"Група"
verbose_name_plural=u"Групи"
title=models.CharField(max_length=256,blank=False,verbose_name=u"Назва")
leader=models.OneToOneField('Student',verbose_name=u"Староста",blank=True,null=True,on_delete=models.SET_NULL)
notes=models.TextField(blank=True,verbose_name=u"Додаткові нотатки")
def __unicode__(self):
if self.leader:
return u"%s(%s %s)"%(self.title,self.leader.first_name,self.leader.last_name)
else:
return u"%s"%(self.title)

Django - How to filter dropdown based on user id?

I'm not sure how to filter dropdown based on user id.
Not I want for user id 2.
I want exactly like this for user id 2.
Model
#python_2_unicode_compatible # only if you need to support Python 2
class PredefinedMessage(models.Model):
user = models.ForeignKey(User)
list_name = models.CharField(max_length=50)
list_description = models.CharField(max_length=50)
def __str__(self):
return self.list_name
class PredefinedMessageDetail(models.Model):
predefined_message_detail = models.ForeignKey(PredefinedMessage)
message = models.CharField(max_length=5000)
View
class PredefinedMessageDetailForm(ModelForm):
class Meta:
model = PredefinedMessageDetail
fields = ['predefined_message_detail', 'message']
exclude = ('user',)
def predefined_message_detail_update(request, pk, template_name='predefined-message/predefined_message_detail_form.html'):
if not request.user.is_authenticated():
return redirect('home')
predefined_message_detail = get_object_or_404(PredefinedMessageDetail, pk=pk)
form = PredefinedMessageDetailForm(request.POST or None, instance=predefined_message_detail)
if form.is_valid():
form.save()
return redirect('predefined_message_list')
return render(request, template_name, {'form':form})
html file
{% extends "base.html" %}
{% load i18n %}
{% block content %}
<form method="post">{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Submit" />
</form>
{% endblock %}
You can do it in view itself using
form = PredefinedMessageDetailForm(request.POST or None, instance=predefined_message_detail)
form.fields["predefined_message_detail"].queryset= PredefinedMessage.objects.filter(user=request.user)
But filtering happens based on request.user so it should be logged in.Consider that also. Hope this helps

Access fields in Django intermediate model of Groups

I'm creating a model of Group with Person and Membership, all like described in Django docs.
class Person(models.Model):
name = models.CharField(max_length=128)
def __str__(self):
return self.name
class Group(models.Model):
name = models.CharField(max_length=128)
members = models.ManyToManyField(Person, through='Membership')
def __str__(self):
return self.name
class Membership(models.Model):
person = models.ForeignKey(Person)
leader = models.BooleanField(default=False)
group = models.ForeignKey(Group)
I'm just making this all in views, becouse i want to make this "creating groups" as a function in my web app.
views.py:
#login_required
def groups(request):
user = request.user
if request.method == "POST":
form = GroupForm(request.POST)
if form.is_valid():
formm = form.save(commit=False)
g = Group.objects.create(name = formm.name)
p = Person.objects.create(name=request.user)
m = Membership.objects.create(person=p, group=g, leader=True)
gr = Group.objects.all()
per = Person.objects.all()
mem = Membership.objects.all()
context = {
'gr': gr,
'per':per,
'mem':mem,
'form': form,
}
return render(request, 'groups.html', context )
else:
gr = Group.objects.all()
per = Person.objects.all()
mem = Membership.objects.all()
form = GroupForm()
context = {
'gr': gr,
'per':per,
'mem':mem,
'form': form,
}
return render(request, 'groups.html', context)
groups.html:
{% block profile %}
<div class="jumbotron">
<h4>Create a new group here:</h4>
<form method="POST" class="post-form">
{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="save btn btn-default">Go!</button>
</form>
</div>
{% for m in mem %}
<div class="jumbotron">
<br>
<p><b>Name of group:</b> {{ m.group }} </p>
<p><b>Member:</b> {{ m.person }} </p>
<br>
</div>
{% endfor %}
{% endblock %}
The problem is when I want to use
Membership.objects.filter(person=request.user)
and get error:
ValueError at /groups/
Cannot query "damian": Must be "Person" instance.
where damian is the name of the request.user
I just want to filter this to show in template only chosen memberships, groups etc...
Any one know how to fix this?
Do like this,
Membership.objects.filter(person__name=request.user)
or
p = Person.objects.get(name=request.user)
Membership.objects.filter(person=p)
You must pass a Person class instance to person argument in Membership filter query.

Categories

Resources