i have this model :
class Member(models.Model):
profile = models.OneToOneField(Profile, editable=False, null=True)
title = models.CharField(max_length=4, choices=TITLE_TYPES, null=True)
name = models.CharField(max_length=100, null=True, verbose_name='Name')
lastname = models.CharField(max_length=100, null=True, verbose_name='LastName')
gender = models.CharField(max_length=1, choices=GENDER_CHOICES, null=True, verbose_name='Gender')
dob = models.DateField('dob')
redressno = models.CharField(max_length=100, null=True, verbose_name='RedressNo')
form :
class MemberForm(ModelForm):
dob = forms.DateField(required=False, input_formats=('%Y-%m-%d', '%m/%d/%Y', '%m/%d/%y'))
class Meta:
model = Member
exclude = ('profile',)
view :
MemberFormSet = formset_factory(MemberForm, formset=BaseFormSet)
print request.method
if request.method == 'POST': # If the form has been submitted...
signup_form = SignupForm(None, request.POST) # A form bound to the POST data
# Create a formset from the submitted data
member_formset = MemberFormSet(request.POST, request.FILES)
# import pdb; pdb.set_trace()
if signup_form.is_valid() and member_formset.is_valid():
print 'in valid'
signup = signup_form.save(request.POST)
for form in member_formset.forms:
member = form.save(commit=False)
member.profile = signup
# import pdb; pdb.set_trace()
member.save()
#log-in to user
user = authenticate(username = request.POST['username'], password = request.POST['password'] )
auth_login(request, user)
return redirect("/main") # Redirect to a 'success' page
else:
signup_form = SignupForm()
data = {
'form-TOTAL_FORMS': u'1',
'form-INITIAL_FORMS': u'0',
'form-MAX_NUM_FORMS': u''
}
member_formset = MemberFormSet(data)
# member_formset.total_form_count=0
# For CSRF protection
# See http://docs.djangoproject.com/en/dev/ref/contrib/csrf/
c = {
'form': signup_form,
'member_formset': member_formset,
}
c.update(csrf(request))
return render_to_response('registration.html', c, RequestContext(request))
Template :
<form action="/registration/" method="POST">
{% csrf_token %}
<div class="section">
{{ form.as_p }}
</div>
<h2>Members</h2>
{{ member_formset.management_form }}
{% for form in member_formset.forms %}
<div class="item">
{{ form.as_table }}
<p style=""><a class="delete" href="#">Delete</a></p>
</div>
{% endfor %}
<p><a id="add" href="#">Add another item</a></p>
<input type="submit" value=" Submit " />
and validation on memberform is not working .Please suggest why ?
You don't really explain your problem, but I'd guess you're not proceeding to validation of the member formset if the signup form isn't valid, because of this line:
if signup_form.is_valid() and member_formset.is_valid():
In Python, as in many other languages, and is shortcut-evaluated: that is, if the first element is False, the second is never evaluated. So is_valid is never run on the formset, so no errors are shown.
Instead, do this:
signup_valid = signup_form.is_valid()
formset_valid = member_formset.is_valid()
if signup_valid and formset_valid:
which ensures that both validations are performed separately.
Firstly, I don't see an else branch for invalid forms. Secondly, isn't the first parameter , None, erroneous for the form initialization in this line: signup_form = SignupForm(None, request.POST).
Related
Account is my AUTH_USER_MODEL and AccountDisplayInfo consists of all the additional display info of every account. So they can input and submit, and subsequently update their information. These are my codes, but I'm unsure why it isn't working. First of all, I am receiving this error:
DoesNotExist at /account/5/displayinfo/ AccountDisplayInfo matching query does not exist.
Secondly, the "update" function isn't working.
models.py
class Account(AbstractBaseUser):
email = models.EmailField(verbose_name="email", max_length=60, unique=True)
username = models.CharField(max_length=30, unique=True)
class AccountDisplayInfo(models.Model):
account = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
instagram = models.CharField(max_length=50, unique=True, blank=True, null=True) #instagram
.html
<form method="POST" enctype="multipart/form-data">{% csrf_token %}
{{ form.as_p }}
<div class="d-flex justify-content-center">
<button type="submit" class="btn btn-primary btn-sm col-lg-5">Update</button>
</div>
</form>
views.py
def display_information_view(request, *args, **kwargs):
user_id = kwargs.get("user_id")
account = Account.objects.get(pk=user_id)
context = {}
displayinfo = AccountDisplayInfo.objects.get(account=account)
if request.POST:
form = DisplayInformationForm(request.POST, request.FILES, instance=request.user)
if form.is_valid():
info = form.save(commit=False)
info.account = request.user
info.save()
messages.success(request, 'Your profile display information have been updated', extra_tags='editdisplayinfo')
return redirect("account:view", user_id=account.pk)
else:
form = DisplayInformationForm(request.POST, instance=request.user,
initial={
"instagram": displayinfo.instagram,
}
)
context['form'] = form
else:
form = DisplayInformationForm(
initial={
"instagram": displayinfo.instagram,
}
)
context['form'] = form
return render(request, "account/displayinfo.html", context)
forms.py
class DisplayInformationForm(forms.ModelForm):
class Meta:
model = AccountDisplayInfo
fields = ('instagram')
Also, would be great if you can advise on this::
If I have 2 tables. Table 1 and Table 2. Table 2 has a foreign key to table 1 but table 1 dont have a foreign key to table 2. How can I query table 2's data from table 1? Thanks
By default .get() will return a DoesNotExist exception if no object matches the query you executed and stop the code from running, so if you want to input it manually on the same page use filter instead:
displayinfo = AccountDisplayInfo.objects.filter(account=account).first()
Then in your template do something like this:
{% if displayinfo %}
... show display info...
{% else %}
<p> No info yet </p> <!-- (or show some form) -->
{% endif %}
To answer your other question:
You have to use the related_name or related models attribute to access the ForeignKey data or use the model name with the _set suffix, for example:
class Post(models.Model):
title = models.CharField(max_lenght=10)
class Comment(models.Model):
body = models.CharField(max_lenght=200)
post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='comments')
then you would get the Post and its comments:
post = Post.objects.get(pk=1)
comments = post.comments.all()
if you didn't have the related_name attribute in your model field you would do this instead:
comments = post.comment_set.all()
UPDATE
Maybe the issue is in your Form class, try removing the save method from it and instead do this in your view:
if request.POST:
form = DisplayInformationForm(request.POST, request.FILES, instance=request.user)
if form.is_valid():
info = form.save(commit=False)
info.account = request.user
messages.success(request, 'Your profile display information have been updated', extra_tags='editdisplayinfo')
info.save()
return redirect("account:view", user_id=account.pk)
I'm using Django. I need a form that shows the 3 fields of a class that I have created, the idea is that every time you want to add a new day and time to start and end, show a new new section, so that each teacher can be found in more of a day and time of beginning and end (the three fields go together)
I still do not logo to make it work, if someone has any idea they would be grateful.
Models.py
class Profesor(Person):
legajo = models.IntegerField(blank=True, null=True)
type = models.CharField(max_length=30)
matter = models.CharField(max_length=100, blank=True, null=True)
calendar = models.ForeignKey('calendar', on_delete=models.DO_NOTHING)
user = models.CharField(max_length=20, blank=True, null=True)
class calendar(models.Model):
day = models.DateTimeField(default=date.today().isoweekday())
hs_init = models.DateTimeField(default=datetime.now().hour)
hs_end = models.DateTimeField(default=datetime.now().hour)
Forms.py
class addProfesorForm(ModelForm):
calendar = forms.ModelChoiceField(queryset=calendar.objects.all(), widget=forms.HiddenInput())
class Meta:
model = Profesor
TYPES = (
('Motiv', 'Motiv'),
('Academic', 'Académic'),
('Otro', 'Otro')
)
help_texts = {
'matter': 'message'
}
fields = ['id', 'type', 'matter']
widgets = {
'type': Select2Widget(choices=typeS)
}
class calendarForm(ModelForm):
class Meta:
model = calendar
fields = ['day','hs_init','hs_end']
Views.py
def agregarTutor(request):
if request.method == 'POST':
form = addProfesorForm(request.POST['calendar'])
calendar=calendar.objects.all()[0]
if form.is_valid():
id = form.cleaned_data['id']
try:
person_Sysatem = SysatemPerson.objects.get(pk=id)
alumn_Sysatem = SysatemAlumn.objects.get(pk=id)
except SysatemPerson.DoesNotExist:
return render(request, 'menu/new-Profesor.html',
{'new_manual': True, 'not_found': True, 'nbar': 'profesors', 'id': id})
new_Profesor = Profesor(
nombre=person_Sysatem.nombre.rstrip(),
id=person_Sysatem.numerodocu,
legajo=alumn_Sysatem.legajo,
telefono=person_Sysatem.telefono.rstrip(),
mail=person_Sysatem.mail.rstrip(),
type=form.cleaned_data['type'],
calendar=form.cleaned_data['calendar'],
matter=form.cleaned_data['matter'],
user=id,
)
Profesor.save(new_Profesor)
contrasena = 'id'+str(id)[0:5]
user = User.objects.create_user(id, person_Sysatem.mail.rstrip(), contrasena)
user.first_name = person_Sysatem.nombre.rstrip()
user.save()
form = addProfesorForm(initial={'calendar':calendar})
return render(request, 'menu/new-Profesor.html', {'form': form, 'Profesor': new_Profesor, 'success': True, 'nbar': 'profesors'})
else:
return render(request, 'menu/new-Profesor.html', {'form': form, 'error_form': True, 'nbar': 'profesors'})
else:
form = addProfesorForm()
return render(request, 'menu/new-Profesor.html', {'form': form, 'nbar': 'profesors'})
Template.html
<h2>new Profesor</h2>
<div class="row">
<div class="col">
<form method="post">{% csrf_token %}
{% include 'common/form_template.html' with form=form %}
<button type="submit" style="margin-top: 10px; float: right;" class="btn btn-primary">Add</button>
</form>
</div>
</div>
Problem description: UserProfile form doesn't save any data.
I am creating a new User and automatically create a UserProfile object for him (so I'm extending UserProfile), so I can go to admin page and fill all the fields . But when I'm trying to do it from client side, my form just doesn't catch the data.
Also the strangest moment is that I can change username and email using UserChangeForm, so I'm trying to do the same for UserProfileObject.
models.py:
class UserProfile(models.Model):
user = models.OneToOneField(User)
image = models.ImageField(upload_to='profile_image', blank=True)
title = models.CharField(max_length=100, default = '')
first_name = models.CharField(max_length=200, default = '')
last_name = models.CharField(max_length=200, default = '')
subject = models.ManyToManyField('Subject', related_name='tutor_type', default = '', help_text="Select a subject")
AREA_STATUS = (
('Jerusalem', 'Jerusalem'),
('Tel Aviv', 'Tel Aviv'),
('Haifa', 'Haifa'),
('Eilat', 'Eilat')
)
area = models.CharField(max_length=200, choices=AREA_STATUS, blank=True, default='', help_text='Tutor area')
# Foreign Key used because tutor can only have one area, but area can have multiple tutors
# Author as a string rather than object because it hasn't been declared yet in file.
description = models.TextField(max_length=4000, help_text="Enter a brief description about yourself")
charge = models.IntegerField(default = '0')
# ManyToManyField used because Subject can contain many tutors. Tutors can cover many subjects.
# Subject declared as an object because it has already been defined.
LANGUAGE_CHOICES = (
('English','English'),
('Hebrew','Hebrew'),
('Russian','Russian'),
('French','French'),
('Arabic','Arabic'),
)
language = models.CharField('Language', choices = LANGUAGE_CHOICES, max_length=50, null=True)
def __str__(self):
return self.user.username
def display_subject(self):
"""
Creates a string for the subject. This is required to display subject in Admin.
"""
return ', '.join([ subject.name for subject in self.subject.all()[:3] ])
display_subject.short_description = 'Subject'
def create_profile(sender, **kwargs):
if kwargs['created']:
user_profile = UserProfile.objects.create(user=kwargs['instance'])
post_save.connect(create_profile, sender = User)
forms.py::
class EditProfileForm(UserChangeForm):
class Meta:
model = User
fields = (
'username',
'email',
'password'
)
class EditExtendedProfileForm(UserChangeForm):
class Meta:
model = UserProfile
fields = '__all__'
exclude = ('user',)
views.py:
def edit_profile(request):
if request.method == 'POST':
form = EditProfileForm(request.POST, instance=request.user)
if form.is_valid():
form.save()
return redirect(reverse('accounts:view_profile'))
else:
form = EditProfileForm(instance=request.user)
args = {'form': form}
return render(request, 'accounts/edit_profile.html', args)
def edit_extended_profile(request):
if request.method == "POST":
form = EditExtendedProfileForm(request.POST, instance=request.user)
if form.is_valid():
form.save()
return redirect(reverse('accounts:view_profile'))
else:
return redirect(reverse('accounts:edit_extended_profile'))
else:
form = EditExtendedProfileForm(instance = request.user)
args = {'form':form}
return render(request, 'accounts/edit_extended_profile.html', args)
edit_extended_profile.html:
{% extends "base.html" %}
{% block head %}
<title>Profile</title>
{% endblock %}
{% block body %}
<div class = "container">
<form method="POST">
{% csrf_token %}
{{form.as_p}}
<button type = "submit" class = "btn btn-success">Submit</button>
</form>
</div>
{% endblock %}
and it is the same template as for edit_profile view.
No traceback, no errors. Any help will be appreciated. Thanks in advance.
I am getting confused on how to implement this. Basically, I have edit_profile page where after login, user gets redirected to this page to fill in his profile. User can fill in his data, click save and then it saves the data in MySQL and comes back to the same edit_profile with all the fields fill in from database.
#app.route("/edit_profile", methods=['GET','POST'])
#login_required
def edit_profile():
custprofileform = CustProfileForm()
if request.method == "POST" and custprofileform.validate_on_submit():
get_user_profile = CustProfileTB.query.filter_by(cust_id = current_user.id).first()
if get_user_profile is None:
profiledata = CustProfileTB(first_name=custprofileform.first_name.data,
last_name= custprofileform.last_name.data,
first_line_address=custprofileform.first_line_address.data,
second_line_address=custprofileform.second_line_address.data,
postcode=custprofileform.phone.data,
phone=custprofileform.phone.data,
agree_tos=custprofileform.agree_tos.data,
cust_id=current_user.id)
db.session.add(profiledata)
db.session.commit()
flash("Customer profile saved successfully")
return render_template("edit_profile.html", first_name=custprofileform.first_name.data)
else:
#profile already exists, so update fileds
profiledata = CustProfileTB(obj=get_user_profile)
db.session.commit()
return render_template("edit_profile.html", first_name=custprofileform.first_name.data)
if request.method == 'GET':
data_to_populate = CustProfileTB.query.filter_by(cust_id=current_user.id).first()
if data_to_populate:
return render_template("edit_profile.html", custprofileform=data_to_populate)
return render_template("edit_profile.html", custprofileform=custprofileform)
my question is, is this correct way to do it?
At the moment, data gets saved in SQLite, but then the form is shown, I see empty textboxes.
Am I passing in the values correctly after form save?
How do I pass values after save?
Can I show it as simple as {{ first_name }}
my Model is :
class CustProfileTB(db.Model):
id = db.Column(db.Integer(), primary_key=True)
first_name = db.Column(db.String(50))
last_name = db.Column(db.String(50))
first_line_address = db.Column(db.String(255))
second_line_address = db.Column(db.String(255))
postcode = db.Column(db.String(255))
phone = db.Column(db.String(20))
agree_tos = db.Column(db.Boolean(), default=False)
cust_id = db.Column(db.Integer())
def __init__(self, first_name=None, last_name=None, first_line_address=None, second_line_address=None, postcode=None, phone=None, agree_tos=None, cust_id=None ):
self.first_name = first_name
self.last_name = last_name
self.first_line_address = first_line_address
self.second_line_address = second_line_address
self.postcode = postcode
self.phone = phone
self.agree_tos = agree_tos
self.cust_id = cust_id
def __repr__(self):
self.res = self.first_name+" "+self.last_name
return '<CustProfileTB {self.res}>'.format(self=self)
When I query from sqlite like :
CustProfileTB.query.filter_by(cust_id=4).first()
I just get what I mentioned in repr which is first_name and last_name. How do I get all the fields and how do I display this data in the form...?
and this does not work:
<label class="col-lg-3 control-label">First Name</label>
<div class="col-lg-8">
{{ custprofileform.csrf_token }}
{% if not first_name %}
<input type="text" name="first_name" placeholder="Insert First Name" data-required="true" class="form-control">
{% else %}
<input type="text" name="{{ first_name }}" placeholder="Insert First Name" data-required="true" class="form-control">
{% endif %}
</div>
When I run this code, even the whole data is correct.
demobilized_formset.is_valid() gives me False and demobilized_formset.errors gives {u'id': [u'Select a valid choice. That choice is not one of the available choices.']}
I don't know why an error comes to id as {u'id': [u'Select a valid choice. That choice is not one of the available choices.']}
managers.py
class DemobilizedEmployee(models.Manager):
use_for_related_fields = True
def get_queryset(self):
# When I use filter instead of exclude it works fine.
return super(DemobilizedEmployee, self).get_queryset().exclude(
demobilized_date=None)
models.py
class PurchasedEmployees(AuditDeleteSafeModel):
purchase = models.ForeignKey(Purchase)
employee = models.ForeignKey(Employee)
category = models.CharField(max_length=32)
mobilized_date = models.DateField()
demobilized_date = models.DateField(null=True, blank=True)
period_worked = models.PositiveSmallIntegerField(null=True, blank=True)
mobilized_emp = MobilizedEmployee()
demobilized_emp= DemobilizedEmployee()
objects = # Is also an custom Manager which changes deleted=True in Abstract Model
class Meta:
db_table = 'purchased_employees'
forms.py
class DetailMobilizeForm(forms.ModelForm):
class Meta:
model = PurchasedEmployees
fields = ('employee', 'category', 'mobilized_date',
'demobilized_date', 'period_worked')
DetailMobilizeInlineFormSet = modelformset_factory(
PurchasedEmployees, can_delete=False, extra=0, form=DetailMobilizeForm)
views.py
def update_demobilize_emp(request, id=None):
purchase = get_object_or_404(Purchase, id=id) if id else Purchase()
demobilized_queryset = PurchasedEmployees.demobilized_emp.filter(
purchase=purchase)
if request.POST:
demobilized_formset = DetailMobilizeInlineFormSet(
data=request.POST,
prefix='demobilized_form')
if demobilized_formset.is_valid():
demobilized_formset.save()
status_code, res = 200, {'status': 'true'}
else:
for form in demobilized_formset:
import ipdb; ipdb.set_trace()
errors = {}
errors[demobilized_formset.prefix + '_errors'] =\
demobilized_formset.errors
status_code, res = 202, {'error': errors , 'status': 'false'}
return HttpResponse(
json.dumps(res), content_type='application/json',
status=status_code)
else:
demobilized_formset = DetailMobilizeInlineFormSet(
queryset=demobilized_queryset,
prefix='demobilized_form')
return render_to_response(
'purchase/update_demobilized_employees.html', {
'demobilized_formset': demobilized_formset, 'purchase': purchase},
context_instance=RequestContext(request))
template
<div class="field">
{{ demobilized_formset.management_form }}
<div class="box">
{% for forms in demobilized_formset.forms %}
<div class="box_item">
{{ forms }}
<br class="clear">
</div>
{% endfor %}
</div>
And
...
<label for="id_demobilized_form-0-period_worked">Period worked:</label>
<input id="id_demobilized_form-0-period_worked" type="number" value="100" name="demobilized_form-0-period_worked" min="0">
<input id="id_demobilized_form-0-id" type="hidden" value="8" name="demobilized_form-0-id">
<ul class="errorlist">
<li>Select a valid choice. That choice is not one of the available choices.</li>
</ul>