Uploading to a Django DataBase from a template - html

I am trying to create a webpage where you can upload questions to the Questions database. I was wondering is there any easy way to do this in Django? Can I upload it so it will be accessible from the Django admin? Here is what I have.
#Models
class Question(models.Model):
question = models.CharField(max_length=400)
answer = models.CharField(max_length=400)
def __unicode__(self):
return self.question + "?"
class QuestionForm(ModelForm):
class Meta:
model = Question
fields = ['question', 'answer']
#Question Template
<div class="container" align="center">
<div class="hero-unit3" align="center">
<h3>
Feel free to post some questions, and a DarKnight representative will answer them for you.
</h3>
</div>
</div>
</div>
<div class="row">
<div class="span6">
<h4>
<form action="<!-- NO IDEA WHAT TO DO -->" method="post">
<input type="text" name="question" />
</div>
</div>
</div>
#views.py
class question(generic.ListView):
template_name = 'users/question.html'
context_object_name = 'Question_list'
def get_queryset(self):
return Question.objects.order_by('question')

The easiest way to achieve what you need is to use CreateView.
In views.py:
from django.views.generic.edit import CreateView
from yourapp.models import Question
class QuestionCreate(CreateView):
model = Question
fields = ['question', 'answer']
Create a new template name question_form.html:
<form action="" method="post">{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Create" />
</form>
Hope it helps!

To make a model available to django admin you have to register the model to admin by
from django.contrib import admin
class Question(models.Model):
...
admin.site.register(Question)
Also for doing this from custom template you can use a model form
The form can be displayed in the template as a table or as a paragraph.
Suppose you render the form to the template as f, use it in template as follows
<form action='..' method='post'>
{{ f.as_t }} //or f.as_p for paragraph
</form>

Related

Django display search bar values as multiple choice check boxes and then subbmit them to the database through a form

I have a form that gathers additional inforrmation about an user and one of its fields is a ManyToMany relationship (it stores data about ski resorts) and i want the following :
to make for the ManyToMany field, from the form, a search bar.
to display all the searched items as check boxes
then check ( if wanted) and submit them How should i approach this ?
I did the following
views.py
class CreateInfoView(CreateView):
model = AdditionalInfoModel
form_class = AdditionallnfoModelForm
template_name = "user_ski_experience/additional_info.html"
def get_form_kwargs(self):
variable_to_send = super(CreateInfoView, self).get_form_kwargs()
variable_to_send.update({'pk': None})
variable_to_send.update({'pk_user': self.request.user.id})
return variable_to_send
def get_success_url(self):
return reverse('login')
class SearchResultsView(ListView):
model = AdditionalInfoModel
template_name = 'user_ski_experience/search_results.html'
def get_queryset(self):
q = self.request.GET.get('q', '')
selected_resorts = Resorts.objects.filter(name__icontains = q)
return selected_resorts
forms.py
class AdditionallnfoModelForm(forms.ModelForm):
class Meta:
model = AdditionalInfoModel
fields = '__all__'
widgets = {'user': forms.HiddenInput(),
'resort_choice': forms.SelectMultiple()}
def __init__(self, pk, *args, **kwargs):
pk_user = kwargs.pop('pk_user', None)
super(AdditionallnfoModelForm, self).__init__(*args, **kwargs)
self.pk = pk
self.fields['user'].disabled = True
self.fields['user'].initial = User.objects.last()
for el in self.fields:
self.fields[el].label = False
def clean(self):
return self.cleaned_data
additional_info.html
<body>
<form method = "post">
{% csrf_token %}
<h1> Let's get started with some questions ! </h1>
<h2> This will help us get to know your ski experience </h2>
<p> {{form.user|as_crispy_field}} </p>
<li> What country do you live in ? {{form.country|as_crispy_field}} </li>
<li> What city do you live in ? {{form.city|as_crispy_field}} </li>
<li> How would you rank yourself as a skier ?
{{form.assumed_technical_ski_level|as_crispy_field}} </li>
<li> How many years of ski experience do you have ?
{{form.years_of_experience|as_crispy_field}} </li>
<li> How much ar you willing to spend ?
{{form.money_to_spend|as_crispy_field}} </li>
<li> {{form.resort_choice|as_crispy_field}} </li>
<br>
<br>
{{form.errors}}
<button id = "1" type="submit" onclick = "{% url 'login' %}">Submit</button>
</form>
<form action="{% url 'user_ski_experience:search' %}" method="get">
<input name="q" type="text" placeholder="Search...">
</form>
<br>
</body>
search_results.html
<body>
<form method = "Post">
{% csrf_token %}
{% for el in object_list %}
<input type = "checkbox" id = "resorts1" name = "resorts" value = "a">
<label for = "resorts1"> {{el.name}} </label>
<br>
{% endfor %}
<button type="submit">Submit</button>
</form>
</body>
What i would like is that the search checked values to be displayed on the additional_info.html views and then subbmited in the database
Like the values displayed in this image search_bar.htm to be displayed in additional info form html and be able to check them

Redirecting into another page in Django

I am working in a project in Django where someone tries to fill the info of some patients and after hitting the submit button i would like o redirect it into a page with the list of all the existing patients, i am trying using a action tag in the html but it seems not to work, i would like to know what i am doing wrong.
html
{%extends 'base.html'%}
{%load staticfiles%}
{%block body_block%}
<link rel="stylesheet" href="{%static 'patients/css/patientform.css'%}">
<form action="{% url 'patients'%}" method="POST">
<div class="wrapper">
{%csrf_token%}
<div class="Patient">
<h3>Informacion del Paciente</h3>
{{patientinfo.as_p}}
</div>
<div class="Medical">
<h3>Informacion Medica</h3>
{{medicalinfo.as_p}}
</div>
<div class="Insurance">
<h3>Informacion de Seguro</h3>
{{insuranceinfo.as_p}}
</div>
<div class="FirstRelative">
<h3>Antecedentes Familiares</h3>
<h5>Primer Caso</h5>
{{first_relative.as_p}}
<h5>Segundo Caso</h5>
{{second_relative.as_p}}
</div>
</div>
<input id="submit" type="submit" value="Agregar">
</form>
{%endblock%}
Url patterns
from django.urls import path
from .views import *
urlpatterns = [
path('',PatientsList.as_view(),name='patients'),
path('addpatient',PatientFormView,name='addpatient'),
]
Redirection should be made after Post request retrieval in your views.py
# AT POST REQUEST END
return redirect("patients")
Django Docs:
https://docs.djangoproject.com/en/3.0/topics/http/shortcuts/#redirect
In the end of your PatientFormView you should redirect with use of:
return redirect("patients")
For more details check Django documentation: docs.djangoproject.com/en/3.0/topics/http/shortcuts/#redirect

Django project - crispy forms not rendering in the browser

As part of a Django project, I have created the following in the views.py file
def profile(request):
u_form =UserUpdateForm()
p_form =ProfileUpdateForm()
context={
'u-form': u_form,
'p-form': p_form
}
I am now trying to render these forms on the html page (profile.html) with the following code:
{% extends "socialmedia/base.html" %}
{% load crispy_forms_tags %}
{% block content %}
<div class="content-section">
<div class="media">
<img class="rounded-circle account-img" src="{{ user.profile.image.url }}">
<div class="media-body">
<h2 class="account-heading">{{ user.username }}</h2>
<p class="text-secondary">{{ user.email }}</p>
</div>
</div>
<form method="POST" enctype="multipart/form-data>
{% csrf_token %}
<fieldset class="form-group">
<legend class="border-bottom mb-4">Profile Information</legend>
{{u_form|crispy}}
{{p_form|crispy}}
</fieldset>
<div class="form-group">
<button class="btn btn-outline-info" type="submit">Update....</button>
</div>
</form>
</div>
{% endblock content %}
Everything else is rendering on the page correctly, except for this bit:
{{u_form|crispy}}
{{p_form|crispy}}
There are no errors on running the server, so I am finding it hard to trouble shoot.
The code in the forms.py file is as follows:
from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm
from .models import Profile
class UserRegisterForm(UserCreationForm): #form that inherits from the usercreationform
email = forms.EmailField()
class Meta:
model = User
#when this form validates it creates a new user
#type the fields to be shown on your form, in that order.
fields = ['username','email','password1','password2']
"""this gives us a nested name space for configurations and
keeps the configs in one place. The model that will be affected is
the user model e.g. when we do a form.save it saves it to the user model.
And the fields we have are the fields we want on the form. It shows order too.
"""
#create a model form...this allows us to create a form that#works with a specific database model#
#we want a form that works with our user model
class UserUpdateForm(forms.ModelForm):
email = forms.EmailField()
class Meta:
model = User
fields = ['username','email']
class ProfileUpdateForm(forms.ModelForm):
class Meta:
model= Profile
fields=['image']
My question is:
Could someone tell me why these additional fields (username, email and image update) are not being shown on the profile html above the 'update' button? In what file have I made the mistake. Note: I'd also appreciate an explanation of the rendering of these u-forms, along with the solution(pointing out my error). I understand that u-form is an instance of UserUpdateForm, but not much else.
context={
'u-form': u_form,
'p-form': p_form
}
You just have a typo. Change the - to _

Django upload form with different models

I am building my first Django app and I need to have an upload page where I would be able to upload multiple files in different upload forms. I need different forms and, I guess, models since depending on the form the file has to be stored in a respective folder in my media root and go through different further transformations. I also want different users have different levels of access to these uploads.
So far I have something like this (I have quite a bit of additional code inside functions in views.py that send data to data frames or other programs but I am not posting those:
models.py
class Upload(models.Model):
document = models.FileField(storage=OverwriteStorage(),upload_to=get_file_path)
upload_date=models.DateTimeField(auto_now_add =True)
class Upload_variables(models.Model):
variables = models.FileField(storage=OverwriteStorage(),upload_to=get_file_path_var)
upload_date=models.DateTimeField(auto_now_add =True)
forms.py
from django import forms
from uploader.models import Upload, Upload_variables
class UploadForm(forms.ModelForm):
class Meta:
model = Upload
fields = ('document',)
class UploadFormVar(forms.ModelForm):
class Meta:
model = Upload_variables
fields = ('variables',)
views.py
def home(request):
if request.method=="POST":
img = UploadForm(request.POST, request.FILES)
if img.is_valid():
img.save()
else:
img=UploadForm()
files=Upload.objects.all()
return render(request,'home.html',{'form':img})
def variables(request):
if request.method == 'POST':
var = UploadFormVar(request.POST, request.FILES)
if var.is_valid():
var.save()
else:
var = UploadFormVar()
files_st = Upload_variables.objects.all()
return render(request, 'home.html', {'form_b': var})
HTML
<form action="#" method="post" enctype="multipart/form-data">
{% csrf_token %} {{form}}
<input type="submit" value="Upload" id="submit_form"/>
</form>
<form action="#" method="post" enctype="multipart/form-data">
{% csrf_token %} {{form_b}}
<input type="submit" value="Upload" id="staging"/>
</form>
So I can see 2 Upload buttons but only one 'choose file'....
Thank you for your help!
Currently you are placing the forms in two separate views. You need to put them in the same view like this:
def home(request):
if request.method=="POST":
var = UploadFormVar(request.POST, request.FILES)
img = UploadForm(request.POST, request.FILES)
if img.is_valid():
img.save()
if var.is_valid():
var.save()
else:
img = UploadForm()
var = UploadFormVar()
files=Upload.objects.all()
return render(request,'home.html',{'form': img, 'form_b': var})

Django 'ManagementForm data is missing or has been tampered with' when saving modelForms with foreign key link

I am rather new to Django so this may be an easy question. I have 2 modelForms where there is a ForeignKey to another. My main goal is to save Indicators with a link to Disease (FK), such that for a particular disease, you can have multiple indicators.
With the code below, I get an error when I hit submit that says 'ManagementForm data is missing or has been tampered with'. Also, the code in views.py does not seem to be validating at the 3rd 'if' statement where there is a return HttpResponseRedirect. However, when I check my database, the values from the form have been written. Any ideas on why the error has been raised? and how to fix it?
My code is below:
models.py
#Table for Disease
class Disease(models.Model):
disease = models.CharField(max_length=300)
#Tables for Indicators
class Indicator(models.Model):
relevantdisease = models.ForeignKey(Disease)
indicator = models.CharField(max_length=300)
forms.py
class DiseaseForm(forms.ModelForm):
class Meta:
model = Disease
class IndicatorForm(forms.ModelForm):
class Meta:
model = Indicator
DiseaseFormSet = inlineformset_factory(Disease,
Indicator,
can_delete=False,
form=DiseaseForm)
views.py
def drui(request):
if request.method == "POST":
indicatorForm = IndicatorForm(request.POST)
if indicatorForm.is_valid():
new_indicator = indicatorForm.save()
diseaseInlineFormSet = DiseaseFormSet(request.POST, request.FILES, instance=new_indicator)
if diseaseInlineFormSet.is_valid():
diseaseInlineFormset.save()
return HttpResponseRedirect('some_url.html')
else:
indicatorForm = IndicatorForm()
diseaseInlineFormSet = DiseaseFormSet()
return render_to_response("drui.html", {'indicatorForm': indicatorForm, 'diseaseInlineFormSet': diseaseInlineFormSet},context_instance=RequestContext(request))
template.html
<form class="disease_form" action="{% url drui %}" method="post">{% csrf_token %}
{{ indicatorForm.as_table }}
<input type="submit" name="submit" value="Submit" class="button">
</form>
You have neither diseaseFormSet nor diseaseFormSet's management form in your template, yet you try to instantiate the formset. Formsets require the hidden management form which tells django how many forms are in the set.
Insert this into your HTML
{{ diseaseFormSet.as_table }}
{{ diseaseFormSet.management_form }}