I have a website where user submitted entries are displayed and have an upvote count along with a button to upvote it yourself. These are represented with the Entry model. How do I pass the id of the particular Entry instance the user upvotes to a view?
html:
{% for entry in entries %}
<div id="upvote_count">
<form action="upvote" method="GET">
{% csrf_token %}
{{ entry.upvotes }}
<button id="upvote" type="submit">Upvote</button>
</form>
</div>
{% endfor %}
models.py:
class Entry(models.Model):
#...
upvotes = models.IntegerField( blank = True, null=True)
current url:
url(r'^upvote$', views.upvote),
You can pass it inside a hidden input, such as:
<form ...>
...
<input type="hidden" name="id" value="{{ entry.id }}">
<button ...>
</form>
and access to it in your view:
def upvote(request):
entry_id = int(request.GET.get("id"))
...
Related
I'm trying to get just a basic model and form to show up with mongoengine and WTF forms, and following the basic instructions from the website aren't working for me. I'm sure it's something simple that is missing, but I've never used flask, mongoengine, or WTFforms, so I'm sort of
Here is my schema definition in models.seed
class PlandoSeed(db.Document):
def __init__(self, preset:str='open', num_players:int=2, num_plants:int=1, **entries: dict):
self.__dict__.update(entries)
self.preset = preset
self.num_players = num_players
self.num_plants = num_plants
preset: db.StringField()
num_players: db.IntField(min=2, max=6)
num_plants: db.IntField(min=1, max=6)
seeds :List[PlandoSeed] = [PlandoSeed('standard',2,2), PlandoSeed('open',4,1), PlandoSeed()]
PlandoSeedForm = model_form(PlandoSeed)
Then this is the route/view that I created in views.py:
#app.route('/seeds/create', methods = ['GET', 'POST'])
def create_seed():
form = PlandoSeedForm(request.form)
if request.method == 'POST' and form.validate():
# todo
redirect('/seeds/')
return render_template('new_seed.jinja', form=form)
Finally, this is my 'new_seed.jinja' template:
{% extends 'base.jinja' %}
{% block content %}
<h1>{% block title %} Create Seed {% endblock %}</h1>
<form method="POST" action="/seeds/create/">
{{ form.csrf_token }}
{% for field in form %}
{{ field }}
{% endfor %}
<input type="Submit" value="Go">
</form>
{% endblock %}
My expectation is that the Create Seed page will have a form with the default input for a text field and integer fields. However, the only field that is in the form object in the jinja template is the CSRF token.Here is what it looks like.
And this is the generated HTML for the form:
<h1> Create Seed </h1>
<form method="POST" action="/seeds/create/">
<input id="csrf_token" name="csrf_token" type="hidden" value="ImZkNzMwMTE1NDJmNDM4NmFjY2EwZDU1ODBjNGJiMjZiMDBhNzFmZGQi.YsRdgg.I8r_Q5RXpmV-r2AzlUNAQ0le7XY">
<input id="csrf_token" name="csrf_token" type="hidden" value="ImZkNzMwMTE1NDJmNDM4NmFjY2EwZDU1ODBjNGJiMjZiMDBhNzFmZGQi.YsRdgg.I8r_Q5RXpmV-r2AzlUNAQ0le7XY">
<input type="Submit" value="Go">
</form>
I am trying to create 2 forms and display it in a single Django HTML page. I created 2 Modelform class like this
class CompanyForm(forms.ModelForm):
class Meta:
model = Company
fields = "__all__"
class ToyForm(forms.ModelForm):
class Meta:
model = Toy
fields = "__all__"
In the HTML page I am only able to embed the model = Company. How can I embed the Model = Toy in the same page, what I tried brings up the same Company Form. Here is the html code
<form method="post">
{% csrf_token %}
<h2> Company Form </h2>
{{ form.as_p }}
<input type="submit" value="Submit" />
</form>
<form method="post">
{% csrf_token %}
<h2> Toy Form </h2>
{{ form.as_p }}
<input type="submit" value="Submit" />
</form>
In views.py
from django.shortcuts import render
from myapp.form import CompanyForm, ToyForm
def index(request):
cform = CompanyForm()
tform = ToyForm()
context={'cform':cform, 'tform':tform}
return render(request,"index.html",context)
In HTML Page
<form method="post">
{% csrf_token %}
<h2> Company Form </h2>
{{ cform.as_p }}
<input type="submit" value="Submit" />
</form>
<form method="post">
{% csrf_token %}
<h2> Toy Form </h2>
{{ tform.as_p }}
<input type="submit" value="Submit" />
</form>
When I render the form in HTML, I use this view. the patient_id is used to denote what patient the check in is for and for name display and such.
def Checkin(request, patient_id):
patient = get_object_or_404(PatientInfo, pk=patient_id)
form = forms.PatientCheckinForm()
return render(request, 'patientRecords/checkin.html', {'patient': patient, 'form':form})
When I submit the patient form filled out as a POST method, I still need access to the patient_id. Currently this is the view that accepts the filled form:
def CheckinSubmit(request):
if request.method == 'POST':
form = forms.PatientCheckinForm(request.POST, request.FILES)
if form.is_valid():
instance = form.save(commit=False)
instance.date_time_of_checkin = dt.now()
instance.patient = patient.patient_id
instance.save()
return redirect('patientRecords/index.html')
I want to set the instance.patient to the patient_id that was part of patient from the Checkin view. Is there a way to pass the patient data back along with the POST method or is there another way this can be done?
For reference, here is my template and I am using ModelForm not form.
{% block content %}
<div class="container">
<h1>Patient Checkin</h1>
<h2>{{patient.first_name}} {{patient.last_name}}</h2>
</div>
<div class="container">
<form action="{% url 'patientRecords:checkinsubmit' %}" method="POST" class="form">
{% csrf_token %}
{% bootstrap_form form %}
{% buttons %}
<button type="submit" class="btn btn-primary">Submit</button>
{% endbuttons %}
</form>
</div>
{% endblock %}
Thanks in advance!
You should be able to simply add a hidden input to your form to capture the patient ID:
{% block content %}
<div class="container">
<h1>Patient Checkin</h1>
<h2>{{patient.first_name}} {{patient.last_name}}</h2>
</div>
<div class="container">
<form action="{% url 'patientRecords:checkinsubmit' %}" method="POST" class="form">
<input type="hidden" name="patient_id" value="{{patient.patient_id}}" />
{% csrf_token %}
{% bootstrap_form form %}
{% buttons %}
<button type="submit" class="btn btn-primary">Submit</button>
{% endbuttons %}
</form>
</div>
{% endblock %}
(Note this assumes that the patient ID is accessible from the patient_id property of the patient object.)
Then, in your CheckinSubmit method, you can access this value via request.POST.get('patient_id')
Alternatively, it appears that your check in form loads with the patient ID in the URL. In your CheckinSubmit method, you should be able to access this URL through the request.META.HTTP_REFERER property. You could then parse the URL (e.g., using request.META.HTTP_REFERER.split('/')[len(request.META.HTTP_REFERER.split('/')) - 1] to pull out the patient ID.
Example
<form method="post" action = "{% url 'user_search_from_group' %}">
<div class="module-option clearfix">
<div class="input-append pull-left">
<input type="hidden" name="groupname" value="{{ gpname }}" />
{% csrf_token %}
<input type="text" class="span3" placeholder="Filter by name" id="username3" name="username3" required>
<button type="submit" class="btn" name="submit">
<i class="icon-search"></i>
</button>
</div>
</div>
</form>
Here a hidden field is used to pass a value along form.
def user_search_from_group(request):
if request.method == 'POST':
username3 = request.POST.get('username3')
gname = request.POST.get('groupname')
Using request we are use the value inside view
I am having trouble displaying data from a many-to-many field on my template.
My models looks like so:
class User(models.Model):
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
email = models.EmailField()
password = models.CharField(max_length=255)
class Secret(models.Model):
message = models.TextField(max_length=1000)
posted_by = models.ForeignKey(User)
all_likes = models.ManyToManyField(User, related_name="all_users")
objects = SecretManager()
When a user clicks a like button, the user is associated with the secret via the all_likes field.
In my template, I am displaying all secrets, then a "delete" button if the session ID is equal to the posted_by user ID. Now all I'm trying to do is add the text "you liked this" if the secret's all_likes contains the user, but nothing i'm doing is right.
<table>
{% if secrets %}
{% for secret in secrets %}
<tr>
<td>{{secret.message}}</td>
<td>{{secret.created_at}}</td>
{% if request.session.id == secret.posted_by.id %}
<td>You posted this</td>
<td> <form action="{%url 'secrets:delete_secret' id=secret.id %}" method="POST">
{% csrf_token %}
<input type="submit" name="delete" value="delete">
</form>
{% endif %}
{% if request.session.id != secret.posted_by.id %}
<td> <form action="{%url 'secrets:create_like' user_id=request.session.id secret_id=secret.id %}" method="POST">
{% csrf_token %}
<input type="submit" name="Like" value="Like">
</form>
{% endif %}
////HERE I WANT TO ADD LOGIC TO DiSPLAY "YOU LIKED THIS" IF REQUEST.SESSION.ID IS EQUAL TO SECRET.ALL_LIKES.USER.ID////
</td>
</tr>
{% endfor %}
{% endif %}
</table>
How do I do this seemingly simple task?
Add a custom method in Secret class and decorate it as a property as below
#property
def all_like_ids(self):
return [x.id for x in self.all_likes]
Then in your template do :
{%if request.session.id in secret.all_like_ids %}
{%endif%}
I have two models.
class ArticleCategory(models.Model):
category = models.CharField(max_length=255,blank=False)
class Article(models.Model):
title = models.CharField(max_length=255,blank=False)
body = models.TextField()
pub_date = models.DateTimeField(auto_now_add=True)
category = models.ForeignKey(ArticleCategory,default=1)
Now I have to render a template and save the form for Article model. I have a foreignKey field in my Article Model and because of that I'm not able to save my article form. I want to select a category from dropdown list and save it in my Article model.
How should I code my template for this ?
My views.py function for this is:
def create(request):
if request.POST:
form = ArticleForm(request.POST, request.FILES)
if form.is_valid():
form.save()
return HttpResponseRedirect('/articles/all/')
else:
form = ArticleForm()
args={}
args.update(csrf(request))
args['categories'] = ArticleCategory.objects.all()
args['form'] = form
return render_to_response('create_article.html', args)
My template create_article.html currently looks like this:
<form role="form" action="/articles/create/" method="POST" enctype="multipart/form-data">{% csrf_token %}
<div class="row">
<div class="form-group col-lg-3">
<label></label>
<p>{{form.title}}</p>
</div>
<div class="form-group col-lg-3">
<label>Category</label>
<p>
<select id="id_category">
{% for category in categories %}
<option value="{{ category }}">{{ category.category }}</option>
{% endfor %}
</select>
</p>
</div>
<div class="clearfix"></div>
<div class="form-group col-lg-12">
<label>Body</label>
{{form.body}}
</div>
<div class="form-group col-lg-12">
<button type="submit" class="btn btn-default">Save Article</button>
</div>
</div>
</form>
You don't need to do this manually. If your ArticleForm is ModelForm and doesn't exclude category field then you can just write {{ form.category }} and get dropdown created by django automatically. It uses ModelChoiceField underneath the hood.
replace
<select id="id_category">
{% for category in categories %}
<option value="{{ category }}">{{ category.category }}</option>
{% endfor %}
</select>
with
{{ form.category }}