In Django getting errors based on dropdown selection - django

Getting error when fields are selected from the down. Not seeing why it is throwing error
Django Dropdown form.error: ERROR ALERT:
location_name Select a valid choice. That choice is not one of the available choices.
Here is the model, form, view and html looks like
MODEL
class Code (models.Model):
name = models.CharField(max_length=4, default=None, blank=True)
def __str__(self): return self.name
class Device (models.Model):
code = models.ForeignKey(Code, on_delete=models.CASCADE, null=True)
ip = models.GenericIPAddressField(protocol='IPv4', unique=True)
def __str__(self): return self.ip
class SiteData (models.Model):
site = models.ForeignKey(Code, on_delete=models.SET_NULL, null=True)
site_ip = models.ForeignKey(Device, on_delete=models.SET_NULL, null=True)
site_data1 = models.CharField(max_length=3, default='120')
class CombineData(models.Model):
location = models.ForeignKey(Code, on_delete=models.SET_NULL, null=True)
device = models.ForeignKey(AddData, on_delete=models.SET_NULL, null=True)
locdata = models.ForeignKey(SiteData, on_delete=models.SET_NULL, null=True)
FORM
class CombineData_form(forms.ModelForm):
class Meta:
model = P2_NexusLeafPair
fields = '__all__'
VIEW
def comboView(request, *args, **kwargs):
template_name = 'site_display.html'
code = Code.objects.order_by('-name')
device = Device.objects.order_by('-ip')
sitename = SiteData.objects.order_by('-site')
content = {
'code': code,
'device': device,
'sitename': sitename
}
if request.method == 'POST':
form = CombineData_form(request.POST or None)
print(form.is_valid())
#print(form.errors)
if form.is_valid():
. . .
else:
messages.error(request, form.errors)
else:
form = CombineData_form()
return render(request, template_name, content)
HTML
<form id="comboView" class="post-form" role=form method="POST" action="comboView">{% csrf_token %}
<div name="code" class="dropdown" id="mainselection" required>
<select name="dc_name">
<option class="dropdown-item" value="">---------</option>
{% for item in code %}
<option value="{{ item }}">{{ item }}</option>
{% endfor %}
</div>
<input type="submit" value="Submit" />
</form>
{same as other fields: device, sitename}

{% for item in content %}
{{item.code}}
{% endfor %}
Try that.

Related

Django - How to display multpile choices for Polls app

Following along the Django polls app tutorial, I was wondering if instead of having a Charfield for the choice Model and manually adding every response/choice to the database; Is it possible to have choices?
For example:
class Poll(models.Model):
text = models.CharField(max_length=255)
pub_date = models.DateField()
def __str__(self):
return self.text
class Choice(models.Model):
question = models.ForeignKey(Poll, on_delete=models.CASCADE)
choice_text = models.CharField(max_length=255)
votes = models.IntegerField(default=0)
def __str__(self):
return "{} - {}".format(self.question.text[:25],
self.choice_text[:25])
You have standard choices for every Poll like this:
class Poll(models.Model):
text = models.CharField(max_length=255)
pub_date = models.DateField()
def __str__(self):
return self.text
class Choice(models.Model):
VOTING_CHOICES = (
('Aye', 'Aye'),
('Nay', 'Nay'),
('Abstain', 'Abstain'),
)
question = models.ForeignKey(Poll, on_delete=models.CASCADE)
choice_text = models.CharField(
max_length=7,
choices=VOTING_CHOICES,
default='Aye',
)**
votes = models.IntegerField(default=0)
def __str__(self):
return "{} - {}".format(self.question.text[:25],
self.choice_text[:25])
Poll Detail page
========
{{ poll }}
<form action="" method="post">
{% csrf_token %}
{% for choice in poll.choice_set.all %}
{% for i,k in choice.VOTING_CHOICES %}
<input type="radio"
name="option"
id="choice{{forloop.counter}}"
value="{{ i }}"/>
<label for="choice{{forloop.counter}}">{{ k }}</label>
{% endfor %}
{% endfor %}
<input type="submit" value="Vote">
</form>
views.py
def poll_detail(request, poll_id):
#render poll detail page
poll= get_object_or_404(Poll, id=poll_id)
if request.method =="POST":
print(request.POST)
# Debug to see what data I am posting on form submission
context = {
'poll':poll,
}
return render(request, 'app/poll_detail.html', context)
Does that make sense? Every time I try to implement this, I either get an empty dictionary response when I POST from the form or the options show up in tuples(or do not render at all).

Populate dropdown in template from model choices using Django Rest Framework

I have the model, serializer, viewset and html as follows:
GENDER = (
('MALE', 'Male'),
('FEMALE', 'Female'),
('OTHERS', 'Others'),
)
class Client(BaseModel):
first_name = models.CharField(max_length=256)
last_name = models.CharField(max_length=256, default="", blank=True, null=True)
designation = models.CharField(max_length=256, default="", blank=True, null=True)
gender = models.CharField(max_length=20, choices=GENDER, null=True, blank=True)
class ClientSerializer(QueryFieldsMixin, DynamicFieldsModelSerializer):
name = serializers.SerializerMethodField()
def get_name(self, obj):
return getattr(obj, "first_name", "") + " " + getattr(obj, "last_name", "")
class Meta:
model = Client
fields = '__all__'
#method_decorator(login_required, name='dispatch')
class ClientViewSet(viewsets.ModelViewSet):
model = Client
queryset = model.objects.all()
serializer_class = ClientSerializer
#action(detail=True, methods=['post','get'], renderer_classes=[renderers.TemplateHTMLRenderer])
def update_client(self, request, *args, **kwargs):
object = self.get_object()
context = {"operation": "Update",
"object_id": object.id,
"events": Event.GetEventsForObject(object)}
template_name = 'contact-client.html'
response = Response(context, template_name=template_name)
<form id="client-form" method="" action="" enctype="multipart/form-data" operation="{{operation}}">
{% csrf_token %}
<div class="row">
<div class="columns medium-5 medium-text-left">
<div class="select2-full select-2-full--sm input-rounded">
<label for = "gender" style="text-align: left;" >Gender</label>
<select id="gender" class="js-select2 input-height-sm element-contact" name="gender" validated="false"></select>
<option></option>
</div>
<div id="gender_error" style="display:none">
<p class="help-text"> <span class="form-action-icon error-icon"></span>Please select gender.</p>
</div>
</div>
<div class="columns medium-5 medium-text-left">
</div>
</div>
</form>
When I instantiate the ClientSerializer in shell like this ClientSerializer() then that gender field is shown along with its choices. But I am not able to show it in the template. All the other fields are being passed correctly.
How can I populate the dropdown with the values of choices in template? What should I pass in the option tag to display the choices and send the data to the view?
Use a ChoiceField instead of CharField
Replace this line
gender = models.CharField(max_length=20, choices=GENDER, null=True, blank=True)
with this one
gender = models.ChoiceField(max_length=20, choices=GENDER, null=True, blank=True)
To show all the choices in your template you can do something like this
from my_app.models import gender
context = {"choices" : gender}
response = Response(context,template_name)
And in template
{% for choice in choices %}
<option value="{{ choice }}">{{ choice }}</option>
{% endfor %}
If you are using the django-template then you can create a model form and pass that form as render context and then render that inside a form.
More on model form: https://docs.djangoproject.com/en/3.1/topics/forms/modelforms/

how to access all fields of other models with the help of Forign Key in django

i want to enroll student and want to get student information from student model and course information from course models.
student and course are separate apps.
how i get the list of student names and the list of courses in enroll view
here is a code
Course Model
class course(models.Model):
course_name = models.CharField(max_length=30)
course_fee = models.IntegerField(default=3000)
cr_hrs = models.IntegerField(default=2)
def __str__(self):
return self.course_name
Student Model
class student(models.Model):
first_name = models.CharField(max_length=20)
last_name = models.CharField(max_length=20)
father_name = models.CharField(max_length=30)
dob = models.DateField()
image = models.ImageField(upload_to='images/', null=True)
phone_number = models.BigIntegerField()
email = models.EmailField(unique=True, null=True)
def __str__(self):
return self.first_name
Enroll Model
from course.models import course
from student.models import student
class enroll(models.Model):
student = models.ForeignKey(student, on_delete=models.CASCADE)
course = models.ManyToManyField(course)
enroll_date = models.DateField()
enrolled_by = models.ForeignKey(User, on_delete=models.CASCADE)
fee_paid = models.BooleanField(default=False)
Enroll View
def create(request):
enrolled = enroll.objects
if request.method == 'POST':
if request.POST['student'] and request.POST['course']:
enrolled = enroll()
enrolled.student = request.POST['student']
enrolled.course = request.POST['course']
enrolled.enrolled_by = request.user
enrolled.save()
return redirect('/enroll/list')
else:
return render(request, 'enroll/create.html', {'error': 'All fields are requried.'})
else:
return render(request, 'enroll/create.html', {'enrolled':enrolled})
html file
<form class="needs-validation" novalidate method="POST" action="{% url 'enroll_create' %}" enctype="multipart/form-data" name="student_form">
{% csrf_token %}
<select class="form-control" name="student">
{% for enroll in enrolled.all %}
<option value="{{enroll.student.first_name}}" >{{enroll.student.first_name}} {{enroll.student.last_name}}</option>
{% endfor%}
</select>
<select class="form-control" name="course" >
{% for enroll in enrolled.all %
<option value="{{enroll.course.course_name}}" >{{enroll.course.course_name}}</option>
{% endfor%}
</select>
<button class="btn btn-primary btn-lg btn-block" type="submit">Register</button>
</form>
i got only 1st name in name list and nothing in courses

form.is_valid() always returns false in views.py

form.is_valid() always fails. I tried different ways to handle it but fails every time and it returns false. Please help in figuring out whats wrong with the code.
models.py looks like this -
class Album(models.Model):
album_name = models.CharField(max_length=50, primary_key=True)
place = models.CharField(max_length=50)
date_pub = models.DateTimeField('date published')
def __str__(self):
return self.album_name
class Images(models.Model):
album_name = models.ForeignKey(Album, db_column='album_name')
image_name = models.CharField(max_length=40)
image = models.FileField(null=True, blank=True)
upload_dt = models.DateTimeField(auto_now=True, auto_now_add=False)
like_cntr = models.IntegerField(default=0)
description = models.CharField(max_length=200, null=True)
def __str__(self):
return self.image_name
forms.py is -
class ImagesForm(forms.ModelForm):
description = forms.CharField(required=False)
class Meta:
model = Images
fields = ('album_name', 'description',)
views.py is -
class RandomView(TemplateView):
template_name = 'photos/random.html'
def get(self, request, album_name):
images = Images.objects.filter(album_name=album_name)
context = {'album_name':album_name, 'images' : images}
return render(request, 'photos/random.html', context)
def post(self, request, album_name):
form = ImagesForm(request.POST)
if form.is_valid():
form.save(commit=False)
text = form.cleaned_data['description']
Images.album_name = album_name
form.save()
else:
return HttpResponse("Failed to save")
Templates is -
<h3>Album : {{album_name }}</h3>
{% for image in images %}
<img src="{{image.image.url}}" height="400" width="500">
<h4> {{image.image_name }}</h4>
<form method="POST" action=""> {% csrf_token %}
<span class = "badge">Description</span>
{% if image.description %}
<h4> {{image.description }} </h4>
{% else %}
<input type="text" value=" "/>
<button type="Submit">Submit</button>
{% endif %}
</form>
{% endfor %}
Where is your necessary name and id attributes for your input tag?
<input type="text" name="description" id="id_description"/>
Please try with {{ form.errors }} above "form" tag. And first of all check that what the errors arrive. Then Find the solution based on that error. Let me know if it is helpful or not.

django form how to render the fields

I'm trying to render a form but the fields are not displayed in the HTML.
views.py
#url(r'^boxes/(?P<pk>[0-9A-Za-z-]+)/$', views.show_form, name='box'),
def show_form(request, pk):
box = Box.objects.get(pk=pk)
form = SuggestionForm()
context = {
'box':box,
'form':form
}
return render(request, 'boxes/detail.html', context)
forms.py
class SuggestionForm(ModelForm):
class Meta:
model = Suggestion
fields = ['comment']
detail.html
<h3>{{box.title}}</h3>
<form action="." method="post">{% csrf_token %}
{{ form.as_p }}
<input type="submit" class="btn btn-info" value="Add suggies" />
</form>
My models.py
#python_2_unicode_compatible
class Suggestion(models.Model):
"""
For adding comments (or suggestions)
"""
def __str__(self):
return self.comment[0:10]
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
comment = models.CharField("",max_length=250, blank=True, null=True)
box = models.ForeignKey(Participant, on_delete=models.CASCADE)
created_at = models.DateField(auto_now_add=True)
updated_at = models.DateField(auto_now=True)
The result HTML.. There is no fields in this form. I want to use a function based view.