I'm trying to modify an existing row of my database, it's a from an intermediary table named "CharacterSkill" with an unique together constraint :
models.py
class CharacterSkill(models.Model):
character = models.ForeignKey(Character, on_delete=models.CASCADE)
level = models.IntegerField(default=0)
skill = models.ForeignKey(Skill, on_delete=models.CASCADE)
class Meta:
unique_together = ("character","skill")
I did a form to change the level but I'm unable to save the form, I have two errors messages from both fields "character" & "skill":
Select a valid choice. That choice is not one of the available choices.
Can you help on that please ? :)
My form :
class SkillCreateForm(forms.ModelForm):
class Meta:
model = CharacterSkill
fields = ('skill','level','character',)
my view :
def skill_update(request,skillpk,instancepk):
form = SkillCreateForm(request.POST)
user = User.objects.get (id = request.user.id)
instance = Character.objects.get (id = instancepk)
skill = CharacterSkill.objects.get(id = skillpk)
data = {'character' : instance,
'skill' : skill.skill,
'level' : skill.level,
}
if form.is_valid():
form.save()
return redirect('persomaker:skill_list', instance.id)
else:
form = SkillCreateForm(data)
#form.fields['skill'].widget = HiddenInput()
#form.fields['character'].widget = HiddenInput()
return render(request, 'character/create_skill.html',
{'instance':instance,
'skill':skill,
'form': form,})
based on a book, I changed the way I bounded the form to use instance :
def skill_update(request,skillpk,instancepk):
user = User.objects.get (id = request.user.id)
instance = Character.objects.get (id = instancepk)
skill = CharacterSkill.objects.get(id = skillpk)
if request.method == "POST":
form = SkillModifyForm(request.POST,instance = skill,)
print (skill)
if form.is_valid():
form.save()
return redirect('persomaker:skill_list', instance.id)
else:
form = SkillModifyForm(instance = skill,)
return render(request, 'character/create_skill.html',
{'instance':instance,
'skill':skill,
'form': form,})
Related
I need to get the value of the field that we enter in the form (in this case, these are the days of reservation) and immediately calculate the cost of the reservation based on it
And the problem is that I don’t understand how to get the value of these very fields (so this is not QuerySet request, and not accessing the database)
This is my views:
def booking(request):
error = ''
if request.method == 'POST':
form = BookingForm(request.POST)
if form.is_valid():
booking = form.save(commit=False)
booking.user = request.user
booking.sum = #create sum function
form.save()
return redirect('account')
else:
error = 'Форма не корректна'
form = BookingForm()
context = {
'form': form,
'error': error
}
return render(request, 'bookings/booking.html', context)
And this is models:
class Booking(models.Model):
startdate = models.DateField('Startgdate')
finishdate = models.DateField('Finishdate')
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
sum = models.PositiveIntegerField('Sum')
fullname = models.CharField('Full name', max_length=50)
pnumber = models.PositiveBigIntegerField('Phone number')
def __str__(self):
return self.fullname
class Meta:
verbose_name = 'Booking'
verbose_name_plural = 'Bookings'
thanks in advance
This is needs Ajax (which can be done by JQuery or Fetch API) that runs on input onchange and a simple view that receives that value and return a the value of cost reservation.
I am trying to associate the user with the post. I have two models students is for user and sublists is for user posts with a foreign key(author). I am using MySQL database and using forms to store data into them. when my form.author execute in my HTML file it gives me a list of ids for all users in the databse but I am already logged in and i want to post as the logged in user without choosing. If remove it says my form is not valid which make sense since im not inputing for form.author.Since I'm using MySQL, I'm not using the built-in User authentication method, but instead comparing both email and password with the login form input. Spend too much time on this but hard to get around with this one. Any help would be appreciated
my views.py look like this
def addnew(request):
if request.method == 'POST':
form = Sublist(request.POST)
if form.is_valid():
try:
form.save()
messages.success(request, ' Subscirption Saved')
name = sublist.objects.get(name=name)
return render (request, 'subscrap/main.html', {'sublist': name})
except:
pass
else:
messages.success(request, 'Error')
pass
else:
form = Sublist()
return render(request, 'subscrap/addnew.html', {'form': form})
#login_required(login_url='login')
#cache_control(no_cache=True, must_revalidate=True, no_store=True)
def main(request):
return render(request, 'subscrap/main.html')
def mod(request):
student = students.objects.all()
return render(request, 'subscrap/mod.html' , {'students': student})
My Models.py
class students(models.Model):
fname = models.CharField(max_length=50)
lname = models.CharField(max_length=50)
password = models.CharField(max_length = 50 , null = True)
passwordrepeat = models.CharField(max_length = 50, null = True)
email = models.EmailField(max_length=150)
class Meta:
db_table = "students"
class sublist(models.Model):
author = models.ForeignKey(students, related_name='sublist' ,on_delete=models.CASCADE)
name = models.CharField(max_length=150)
cost = models.IntegerField(default = 0)
renewalcycle = models.IntegerField(default = 0)
class Meta:
db_table = "sublist"
Since I'm using forms here's my forms.py
lass StudentForm(forms.ModelForm):
class Meta:
model = students
fields = "__all__"
class Studentlogin(forms.Form):
email = forms.EmailField(max_length=150)
password = forms.CharField(max_length = 50, widget=forms.PasswordInput)
class Sublist(forms.ModelForm):
class Meta:
model = sublist
fields = "__all__"
Exclude the Author from the Sublist form:
class Sublist(forms.ModelForm):
class Meta:
model = sublist
exclude = ['author']
In the addnew method, you associate the .instance.author with the request.user:
#login_required(login_url='login')
def addnew(request):
if request.method == 'POST':
form = Sublist(request.POST)
if form.is_valid():
form.instance.author = request.user
form.save()
messages.success(request, ' Subscirption Saved')
return redirect('some_view')
else:
messages.error(request, 'Error')
else:
form = Sublist()
return render(request, 'subscrap/addnew.html', {'form': form})
Note: Models in Django are written in PascalCase, not snake_case,
so you might want to rename the model from sublist to Sublist.
Note: Usually a Form or a ModelForm ends with a …Form suffix,
to avoid collisions with the name of the model, and to make it clear that we are
working with a form. Therefore it might be better to use SublistForm instead of
Sublist.
Note: It is normally better to make use of the settings.AUTH_USER_MODEL [Django-doc] to refer to the user model, than to use the students directly. For more information you can see the referencing the User model section of the documentation.
I have a model form that have multiple choice fields. using AJAX to update form choic fields upon changed field.
Model:
class Student(models.Model):
CLASSROOM = 0
GROUPROOM = 1
HOMEROOM = 3
STUDENT_RECORD_TYPES = [
(CLASSROOM,_("Classroom")),
(GROUPROOM,_("Group")),
(HOMEROOM,_("Home Edu")),
]
school = models.ForeignKey(School,on_delete=models.CASCADE,blank=False,related_name='student_records')
grade = models.ForeignKey(Grade,on_delete=models.CASCADE,blank=False,related_name="student_records")
record_type = models.PositiveSmallIntegerField(_("Record Type"),choices=STUDENT_RECORD_TYPES,default=0)
class Meta:
constraints = [
models.UniqueConstraint(
fields=['school','grade', 'record_type'],
name='unique_school_grade_record'
),
]
def __str__(self):
return "Record ID: {}".format(self.pk)
Views.py:
def update_students(request,pk):
updated_table=None
student_record = get_object_or_404(Student,pk=pk)
if request.POST:
form = StudentForm(request.POST or None,instance=student_record)
if form.is_valid():
form.save()
messages.success(request,_("Student record Updated Successfully!"))
#Getting data for view
updated_table = update_students_table(request)
else:
messages.error(request,_("Invalid Input, Please check!"))
else:
form = StudentForm(request.GET or None,instance=student_record)
context = {}
# load form template
context['form'] = form
form_template_path = "components/forms/student_update.html"
html_form = loader.render_to_string(form_template_path, context, request)
context['form'] = html_form
return JsonResponse(context)
Forms.py:
class StudentForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(StudentForm, self).__init__(*args, **kwargs)
for visible in self.visible_fields():
visible.field.widget.attrs['class'] = 'form-control'
self.fields['school'].widget.attrs['class'] += ' select2'
#the issue stands here
#self.data.get('school') returns none even if its exist in form data
if self.data.get('school'):
self.fields['grade'].queryset = Grade.objects.filter(school=self.data.get('school'))
else:
self.fields['grade'].queryset = Grade.objects.none()
class Meta:
model = Student
fields = '__all__'
the strange behavior drives me crazy because when I reselect the school it updates the grade choices normally (with no option selected!), but when I open edit instance form the data is there but grade field have no options in it!
I have a ModelForm, and I want to only pass some of the fields into the template. I would like to save one particular field to define after the POST request has been sent. Here is the ModelForm:
class CreateListingForm(ModelForm):
class Meta:
model = models.ListingModel
fields = ['name', 'image', 'description', 'price', 'category']
widgets = {
'description': Textarea()
}
And here is the Model:
class ListingModel(models.Model):
name = models.CharField(max_length=30)
image = models.ImageField(upload_to='images')
description = models.CharField(max_length=1000)
price = models.PositiveIntegerField()
category = models.CharField(max_length=15)
objects = models.Manager()
owner = models.CharField(max_length=100)
In the next code block, I am attempting to define the owner field according to the current user logged in (request.user.username):
#login_required(redirect_field_name=login_view)
def create_listing(request):
if request.method == "GET":
return render(request, "auctions/createlisting.html", {
"CreateListingForm": forms.CreateListingForm()
})
elif request.method == "POST":
form = forms.CreateListingForm(request.POST, request.FILES)
if form.is_valid():
try:
form.owner = request.user.username
print(form.owner)
form.save(commit=True)
except Exception:
return HttpResponseRedirect(reverse("create_listing_error"))
return HttpResponseRedirect(reverse("index")) #TODO
Now, when I say print(form.owner), the result is correct. However when I save the ModelForm, the owner field is left blank. Am I not defining the value of the owner field correctly?
You should not confuse the ModelForm with the instance it is wrapping. The fact that it prints something for form.owner is not that strange, you first set an attribute named .owner, an attribute that did not exists before. You should set the .owner of the .instance of the form:
#login_required(redirect_field_name=login_view)
def create_listing(request):
if request.method == 'POST':
form = forms.CreateListingForm(request.POST, request.FILES)
if form.is_valid():
form.instance.owner = request.user.username
form.save()
return redirect('name-of-some-view')
else:
form = forms.CreateListingForm()
return render(request, 'auctions/createlisting.html', {
'CreateListingForm': form
})
Where 'name-of-some-view' should be replaced by the name of some view to which you redirect in case the form was valid.
You should however consider changing the CharField of owner to a ForeignKey [Django-doc]. Imagine that later the user changes their username, then your ListingModels do no longer refer to a real user.
I have a form in my application which has a hidden form field, the value of which I want to set in my corresponding view after submitting the form.
forms.py
class EvangelizedForm(forms.ModelForm):
first_name = forms.CharField(help_text="First Name")
last_name = forms.CharField(help_text="Last Name")
email = forms.CharField(help_text="Email ID")
mobile_no = forms.CharField(help_text="Mobile number")
twitter_url = forms.CharField(help_text="Twitter URL")
twitter_followers = forms.CharField(widget = forms.HiddenInput()) #Hidden form field
class Meta:
model = Evangelized
fields = ('first_name','last_name', 'twitter_url', 'email', 'mobile_no')
models.py
class Evangelized(models.Model):
first_name = models.CharField(max_length=128)
last_name = models.CharField(max_length=128)
email = models.EmailField()
mobile_no = models.CharField(unique=True, max_length = 10, validators=[RegexValidator(regex='^\w{10}$', message='Mobile number should be strictly of 10 digits.')])
twitter_url = models.CharField(unique=True, max_length=128)
twitter_followers = models.CharField(max_length = 128)
views.py
def fillform(request):
follower_count = '250'
if request.method == 'POST':
form = EvangelizedForm(request.POST)
if form.is_valid():
form.fields['twitter_followers'] = follower_count
form.save(commit=True)
return index(request)
else:
form.errors
else:
#form = EvangelizedForm()
if request.user.is_authenticated():
form = EvangelizedForm(initial={'first_name': request.user.first_name,
'twitter_url': 'https://twitter.com/' + request.user.username,
'last_name': request.user.last_name})
else:
form = EvangelizedForm()
context = RequestContext(request,
{'request': request,
'user': request.user, 'form':form})
#return render(request, 'rango/fillform.html', {'form': form, 'context_instance':context})
return render_to_response('rango/fillform.html',
context_instance=context)
Basically, I'm trying to set the value of twitter_followers (which is a hidden form field in forms.py) in my index view, by:
follower_count = '250'
..
..
form.fields['twitter_followers'] = follower_count
By doing this, I'm expecting the value of 'twitter_followers' in the database after submitting the form to be '250'. However, this approach doesn't seem to be working.
What's the right way to set values to certain attributes in the database manually using views?
You need to set it on the model instance, which is the result of form.save. That's the main reason for the commit argument in the first place.
if form.is_valid()
obj = form.save(commit=True)
obj.twitter_follower = follower_count
obj.save()
You can override the save method of the form, with something like this:
def save(self, *args, **kwargs)
twitter_followers = kwargs.pop('twitter_followers', 0)
self.instance.twitter_followers = twitter_followers
super(Evangelized, self).save(args, kwargs)
And then in the view just have to call in this way:
form.save(twitter_followers=250)