set a Boolean when submitted in django - python

I want to set a Boolean field is_rep in a retest model to true when the retest form is submitted.
Now it is just get added up in a retest model.
Because I want to trigger other events when the request is submitted.
My code
models.py
class Retest(models.Model):
semester = models.ForeignKey(Semester)
dept = models.ForeignKey(Departement)
batch = models.ForeignKey(Batch)
date = models.DateField(default=0)
subject = models.ForeignKey(Subject)
name = models.CharField(max_length=50)
admnno = models.CharField(max_length=50)
reason = models.CharField(max_length=50)
proof = models.CharField(max_length=200)
is_hod = models.BooleanField(default=False)
is_principal = models.BooleanField(default=False)
notify = models.BooleanField(default=False)
is_sure = models.BooleanField(default=False)
is_rep = models.BooleanField(default=False)
def get_absolute_url(self):
return reverse( 'retest:retestform')
def __str__(self):
return self.name
urls.py
url(r'^retest/retestform/$',login_required(views.RetestCreate.as_view()), name='retestform')
views.py
class RetestCreate(CreateView):
model = Retest
fields = ['semester', 'dept', 'batch', 'date', 'subject', 'name', 'admnno', 'reason', 'proof', 'is_sure']
template
<form class="form_horizontal" action="" method="post" enctype="multipart/form-data" >
{% csrf_token %}
{% include 'retest/form-template.html' %}
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-success">Submit</button>
</div>
</div>
</form>

If you want to set the boolean field to true, when the form is submitted, you just have to handle it in the view.
Submit the form and before saving it into the database just set the is_rep = true.
is_rep is a field which is in the model, but not used in the form.
So, if you want to change that then you have to manually write a view for it. Try to use base view instead of generic views to understand the workflow of the views and forms.
I'd recommend using something like this:
class RetestView(View):
def get(self, request, *args, **kwargs):
..............
return render(request, self.template, {"some_context"}
def post(self, request, *args, **kwargs):
form_data = your_form(request.POST)
if form_data.is_valid():
new_object = form_data.save(commit=False)
new_object.is_rep = True
new_object.save()
return render(request, self.template, {"some...context"})
Hope you got what you were looking for..!

form_template
{% for field in form %}
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<span class="text-danger small">{{ field.errors }} </span>
</div>
<label class="control-label col-sm-2">{{ field.label_tag }} </label>
<div class ="col-sm-12">
<div class="form-control">
{{ field }}</div></div>
</div>
{% endfor %}

Related

Django search / filter across multiple models

In my Django website, I'm trying to create a search bar on my homepage that returns results that are stored in two different models(Articles, Jobs)
Currently, I get an empty result set when I search using this code:
In models.py,
class Articles(models.Model):
objects = None
news_title = models.CharField(db_column="title", max_length=400)
news_url = models.URLField(db_column="link", max_length=400)
image_link = models.CharField(db_column="image", max_length=400)
published_date = models.CharField(db_column="published_date", max_length=400)
class Meta:
managed = False
db_table = "articles"
def __str__(self):
return self.news_title
class Jobs(models.Model):
objects = None
company = models.CharField(db_column='company', max_length=100)
job_title = models.CharField(db_column='job_title', max_length=300)
experience = models.CharField(db_column='experience', max_length=300)
edu_level = models.CharField(db_column='edu_level', max_length=50)
class Meta:
managed = False
db_table = "job_list"
def __str__(self):
return self.job_title
In views.py,
class SearchView(ListView):
template_name = 'blog/search_results.html'
def get_queryset(self):
request = self.request
query = request.GET.get('q', '')
articles_results = Articles.objects.filter(Q(news_title__icontains=query))
jobs_results = Jobs.objects.filter(Q(job_title__icontains=query))
context={
'articles':articles_results,
'jobs':jobs_results,
}
return render(request, 'blog/search_results.html', context)
In main_view.html, I'm using this code for creating a search bar:
<form action="{%url 'search_results' %}" method="get" values="{{request.GET.q}}" class="search-jobs-form">
<div class="row mb-5">
<input name="q" type="text" values="{{request.GET.q}}" placeholder="search">
</div>
<button type="submit">Search</button>
</form>
And in search_results.html,
{% block content %}
{% for job in jobs %}
<h5>{{job.job_title}}</h5>
<p>{{job.company}}</p>
{% endfor %}
{% for article in articles %}
<h5>{{article.news_title}}</h5>
<p>{{article.published_date}}</p>
{% endfor %}
{% endblock %}
I ended up not using class SearchView(ListView) in views.py and made it work
Here's the code that I used
#index.html Search Bar
<form method="get" class="search-jobs-form" action="{% url 'main_search'%}">
{% csrf_token %}
<input type="text" placeholder="Job title, Company..." name="search_query">
<button type="submit" class="btn btn-info btn-lg btn-block text-white btn-search">Search Job</button>
</form>
In views,
#views.py
def main_search(request):
q = request.GET['search_query']
articles = Articles.objects.filter(news_title__icontains=q)
jobs = Jobs.objects.filter(Q(job_title__icontains=q) | Q(company__icontains=q))
return render(request, "blog/main_search.html", {'articles':articles, 'jobs':jobs, 'page_name':'Search Results', 'q':q})

How to redirect to a form after parsing an uploaded csv file if items don't exist in database?

I am having an issue that i have been trying to solve for a few days and feel like I have hit a roadblock and can't find the answers I need. What I am trying to do is:
Upload a csv file (this file basically contains details about stock trades) which will be saved in a table and stored in media directory, the content is then parsed and passed to a dictionary (this step is working) -- the contents of this file will be used to update various tables in my database later.
As I loop through the key, value pairs in the dictionary check to see if certain values exist in various models which are used as foreign keys (this part also works) -- So for example, if a trade is tagged with Fund X and fund X doesn't exist in my Fund table, it will take me to a form to fill in all the required fields to create fund X in my database
If a value is missing I want to be sent to a form that will then allow me to create this value in the database so that I can populate the required fields (this part is partially working, I can get to the form for missing data but I am unable to save the inputs of that form to the data base)
I have a utils.py file that will be containing all of my classes or helper functions to accomplish this.
if i print out fund_form.errors in from my views.py file i get the following:
<ul class="errorlist"><li>fund_code<ul class="errorlist"><li>This field is required.</li></ul></li><li>fund_name<ul class="errorlist"><li>This field is required.</li></ul></li></ul>
Please let me know if you need any other information I have been struggling with this for a few days.
models.py
class Funds(models.Model):
fund_code = models.CharField(max_length=10, primary_key=True)
fund_name = models.CharField(max_length=100, unique=True)
def __str__(self):
return self.fund_code + ' - ' + self.fund_name
class Trades(models.Model):
trade_date = models.DateField(default=timezone.now)
trade_file = models.FileField(upload_to='trades/')
user = models.ForeignKey(User, on_delete=models.PROTECT)
views.py
VALID_FILE_TYPES = ['csv']
def upload_trades(request):
if not request.user.is_authenticated:
return render(request, 'position_mgmt/login.html')
else:
form = UploadFileForm(request.POST or None, request.FILES or None)
if form.is_valid():
trades = form.save(commit=False)
trades.user = request.user
trades.trade_date = request.POST['trade_date']
trades.trade_file = request.FILES['trade_file']
file_type = trades.trade_file.url.split('.')[-1]
file_type = file_type.lower()
if file_type not in VALID_FILE_TYPES:
context = {
'trades': trades,
'form': form,
'error_message': 'File type must be .csv',
}
return render(request, 'position_mgmt/upload_trades.html', context)
trades.save()
trade_upload = ProcessUpload(trades.trade_file.name)
parsed_trades = trade_upload.parse_trades()
database_check = trade_upload.check_database(parsed_trades, request)
if database_check['fund_code']:
fund_form = CreateFundForm(request.POST or None)
database_check['form'] = fund_form
if request.method == 'POST':
if fund_form.is_valid():
fund = fund_form.save(commit=False)
fund.user = request.user
fund.fund_code = request.POST['fund_code']
fund.fund_name = request.POST['fund_name']
fund.save()
return render(request, 'position_mgmt/upload_trades.html', {'trades': trades})
return render(request, 'position_mgmt/positions_form.html', database_check)
return render(request, 'position_mgmt/trade_files.html', {'trades': trades})
context = {'form': form}
return render(request, 'position_mgmt/upload_trades.html', context)
forms.py
class UploadFileForm(forms.ModelForm):
class Meta:
model = Trades
fields = ['trade_date', 'trade_file']
class CreateFundForm(forms.ModelForm):
class Meta:
model = Funds
fields = ['fund_code', 'fund_name']
utils.py
class ProcessUpload:
"""
A class to upload and process trade files
Attributes
----------
name: str
name of the file that will be processed
Methods
-------
parse_trades()
imports csv file from the MEDIA_ROOT and returns a list of dictionaries of format:
[{:,:}, {:,:}......]
check_database()
...
"""
def __init__(self, name):
"""
:param name:
name of the csv file
"""
self.name = name
def parse_trades(self):
file_path = os.path.join(settings.MEDIA_ROOT, self.name)
with open(file_path) as f:
trade_file = csv.DictReader(f, restkey='tags')
return list(trade_file)
def check_database(self, trade_dict, request):
for each_trade in trade_dict:
for _key in each_trade:
if _key == 'fund_code':
if not Funds.objects.filter(fund_code=each_trade[_key]).exists():
return {'fund_code': each_trade[_key],
'error_message': 'fund {0} does not exist'.format(each_trade[_key])}
return None
upload_trades.html
{% extends 'position_mgmt/base2.html' %}
{% block title %}Upload{% endblock %}
{% block body %}
<body>
{% block sub_body %}
{% endblock %}
<br>
<div class="container-fluid">
<div class="row">
<div class="col-sm-12 col-md-7">
<div class="panel panel-default">
<div class="panel-body">
<h3>Upload Trades</h3>
{% if error_message %}
<p><strong>{{ error_message }}</strong></p>
{% endif %}
<form class="form-horizontal" role="form" action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
{% include 'position_mgmt/form-template.html' %}
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-success">Submit</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</body>
{% endblock %}
form-template.html
{% for field in form %}
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<span class="text-danger small">{{ field.errors }}</span>
</div>
<label class="control-label col-sm-4">{{ field.label_tag }}</label>
<div class="col-sm-8">{{ field }}</div>
</div>
{% endfor %}

django modelform how to know input type is checkbook?

My modelform is a dynamically generated modelform,I want to know the type of is_true in the modelForm. The type of the input tag is the checkbook type.
If I know the type=‘checkbox’ of the is_true field, add a class attr to him separately.
The default type='checkbox’ interface is too ugly
models
class Employee(AbstractBaseUser):
"""
用户表
"""
username = models.CharField(max_length=30, verbose_name='姓名')
email = models.EmailField(verbose_name='邮箱', unique=True)
is_true = models.BooleanField(default=False, verbose_name='是否超级用户')
views
class ModelFormDemo(ModelForm):
class Meta:
model = self.model
if self.list_editable:
fields = self.list_editable
else:
fields = '__all__'
excluded = self.excluded
def __init__(self, *args, **kwargs):
super(ModelFormDemo, self).__init__(*args, **kwargs)
def add_view(self, request):
form = ModelFormDemo()
if request.method == "POST":
res_dict = {'status': 1, 'msg': 'success'}
form = ModelFormDemo(request.POST)
if form.is_valid():
obj = form.save()
else:
res_dict['msg'] = form.errors
res_dict['status'] = 2
return JsonResponse(res_dict)
return render(request, "xadmin/add_view.html", locals())
html
<form class="layui-form" method="post">
{% csrf_token %}
{% for field in form %}
{% if field.name == 'employee' %}
<input type="hidden" name="employee" value="{{ user.id }}">
{% else %}
<div class="layui-form-item">
<label class="layui-form-label">{{ field.label }}</label>
<div class="layui-input-inline">
{{ field }}
</div>
</div>
{% endif %}
{% endfor %}
<div class="layui-form-item">
<div class="layui-input-block">
<input type="button" class="layui-btn" lay-filter="add" lay-submit="" value="add">
</input>
<button type="reset" class="layui-btn layui-btn-primary">reset</button>
</div>
</div>
</form>
You can use the Widget.attrs arg in your form __init__ method.
https://docs.djangoproject.com/en/dev/ref/forms/widgets/#django.forms.Widget.attrs

Django select a valid choice error in form when using custom form template

I've been lurking for an answer for quite some time now, but I haven't found solution for my problems.
I made custom template for my form and now, when I try to submit form I get this under choice field: Select a valid choice. is not one of the available choices.
I believe that problems is because I am not passing instance of organization but id. I tried {{ form.instance.organization }} and then I get None where should be choice field
views.py:
class AddNewView(generic.View):
formClass = AddNewForm
template_name = 'myapp/subscription_form.html'
def get(self, request):
groups = self.request.user.groups.values_list('id', flat=True).first()
form = self.formClass(groups, None)
return render(request, self.template_name, {'form': form})
def post(self, request):
groups = self.request.user.groups.values_list('id', flat=True).first()
form = self.formClass(groups, request.POST)
if form.is_valid():
subscription = form.save(commit=False)
organization = request.user.groups.values_list('id', flat=True).first()
input_user = self.request.user
stuff = form.cleaned_data['stuff']
description = form.cleaned_data['description']
subscription.save()
return render(request, self.template_name, {'form': form})
forms.py:
class AddNewForm(forms.ModelForm):
def __init__(self, groups,*args,**kwargs):
super (AddNewView, self ).__init__(*args,**kwargs)
self.fields['organization'].queryset = Organization.objects.filter(group=groups)
class Meta:
model = Subscription
fields = [
'organization',
'stuff',
'description',
]
models.py:
class Organization(models.Model):
d_number = models.CharField(max_length=25)
city = models.CharField(max_length=100)
group = models.ManyToManyField(Group, help_text="groups")
class Subscription(models.Model):
organization = models.ForeignKey(Group, help_text="which organization")
input_user = models.CharField(max_length=150)
input_date = models.DateTimeField(auto_now_add=True)
description = models.CharField(max_length=1000, null=True, blank=True, help_text='Description')
stuff = models.CharField(max_length=100)
template:
<form action="" method="post">
{% csrf_token %}
<!-- Left Inputs -->
<div class="col-xs-6 wow animated slideInLeft" data-wow-delay=".5s">
<!-- Organization -->
{{ form.non_field_errors }}
<div class="fieldWrapper">
{{ form.organization.errors }}
<label>Organization:</label>
{{ form.organization }}
</div>
<!-- stuff -->
{{ form.non_field_errors }}
<div class="fieldWrapper">
{{ form.stuff.errors }}
<input type="text" name="stuff" id="id_stuff" required placeholder="stuff" class="form"/>
</div>
</div><!-- End Left Inputs -->
<!-- Right Inputs -->
<div class="col-xs-6 wow animated slideInRight" data-wow-delay=".5s">
<!-- description -->
{{ form.non_field_errors }}
<div class="fieldWrapper">
<textarea name="description" id="id_description" class="form textarea" placeholder="description"></textarea>
</div>
</div><!-- End Right Inputs -->
<div class="relative fullwidth col-xs-12">
<!-- Send Button -->
<button type="submit" class="form-btn semibold">Vnesi</button>
</div><!-- End Bottom Submit -->
</form>

DJANGO how to handle two forms in one form tag

I have two form Postform and Fileform and i am placing both forms in one tag. but when i press submit button nothing happens. and i also made file field not required but it is still not working. but when i give input to both forms only then it work.
i want if file is not present it should work and just save post form.
form.py
class PostForm(forms.ModelForm):
choice = (
('post','post'),
('anouncement','anouncement'),
('question', 'question')
)
title = forms.CharField(widget=forms.TextInput(attrs={'class':'mdl-textfield__input','id':'s1'}))
content = forms.CharField(widget=forms.Textarea(attrs={'class':'mdl-textfield__input','id':'sample5','rows':'3'}))
post_type = forms.ChoiceField(choices = choice, widget = forms.Select(attrs={'class':'mdl-selectfield__select', 'id':'post_type'}))
class Meta:
model = Post
fields = [
"title",
"content",
"post_type",
]
class FileForm(forms.ModelForm):
file = forms.FileField(widget=forms.ClearableFileInput(attrs={'multiple': True,'class':'none','id':'file_input_file','required':'False'}), required = False )
class Meta:
model = file
fields = [
"file"
]
def __init__(self, *args, **kwargs):
# first call parent's constructor
super(FileForm, self).__init__(*args, **kwargs)
# there's a `fields` property now
self.fields['file'].required = False
views.py:
form = PostForm(request.POST or None)
fileForm = FileForm(request.POST or None, request.FILES or None)
context.update({'form':form, 'fileform':fileForm})
print(fileForm.is_valid())
if form.is_valid() and fileForm.is_valid():
instance = form.save(commit=False)
instance.user = request.user
slug = create_slug(instance)
instance.slug = slug
instance.save()
print(request.FILES)
if request.FILES :
for f in request.FILES.getlist('file'):
print(f)
file.objects.create(Post = instance, file=f)
return HttpResponseRedirect('/%s/post/%s/'%(request.user.username,slug))
template:
<form enctype="multipart/form-data" action="" method="POST">
{% csrf_token %}
{{ form.as_p }}
<span style="display: inline-flex;">
<div class="file_input_div">
<div class="file_input">
<label class="image_input_button mdl-button mdl-js-button mdl-button--fab mdl-button--mini-fab mdl-js-ripple-effect mdl-button--colored">
<i class="material-icons">file_upload</i>
{{ fileform.file}}
</label>
</div>
<div id="file_input_text_div" class="mdl-textfield mdl-js-textfield textfield-demo">
<input class="file_input_text mdl-textfield__input" type="text" disabled readonly id="file_input_text" />
<label class="mdl-textfield__label" for="file_input_text"></label>
</div>
</div>
<div class="mdl-layout-spacer"></div>
<div class="mdl-layout-spacer"></div>
<button class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--colored align-right" name="submit" type="submit">submit</button>
</span>
</form>
Thanks in advance!!

Categories