I am trying to display a username's profile picture in a blog/social media app when some user clicks on some other user's username but it is currently not working.
In my template: (I think my issue is I don't have access to post?)
{% extends "blog/base.html" %}
{% block content %}
<article class="media content-section">
<img class="img-thumbnail account-img mt-3 " src="{{ username.profile.image.url }}">
</article>
<h1 class="mb-3">Posts by {{ view.kwargs.username }} ({{ page_obj.paginator.count }})</h1>
<div class="infinite-container">
{% for post in posts %}
<div class="infinite-item">
<article class="media content-section">
<img class="rounded-circle article-img" src="{{ post.author.profile.image.url }}">
<!-- profile (model in user ).image (attribute) -->
<div class="media-body">
<div class="article-metadata">
<a class="mr-2" href="{% url 'user-posts' post.author.username %}">{{ post.author }}</a>
<small class="text-muted">{{ post.date_posted|date:"F d, Y" }}</small>
</div>
<h2><a class="article-title" href="{% url 'post-detail' post.id %}">{{ post.title }}</a></h2>
<p class="article-content">{{ post.content }}</p>
</div>
</article>
</div>
{% endfor %}
</div>
My users\models.py:
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
image = models.ImageField(default='default.jpg', upload_to='profile_pics')
def __str__(self):
return f'{self.user.username} Profile'
def save(self, *args, **kwargs):
super(Profile, self).save(*args, **kwargs)
img = Image.open(self.image.path)
if img.height > 300 or img.width > 300:
output_size = (300, 300)
img.thumbnail(output_size)
img.save(self.image.path)
In my blog/models.py:
class Post(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
date_posted = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('post-detail', kwargs={'pk': self.pk})
I can retrieve some user's username by {{ view.kwargs.username }}, how can I do this with profile pictures?
my blog\views.py:
from django.shortcuts import render, get_object_or_404
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
from django.contrib.auth.models import User
from django.db.models import Q
from .models import Post #from the model file in the current package import the Post class
from django.views.generic import (
ListView,
DetailView,
CreateView,
UpdateView,
DeleteView
)
def home(request):
context = {
'posts': Post.objects.all(), # querying the database
}
return render(request, 'blog/home.html', context)
class PostListView(ListView):
model = Post
template_name = 'blog/home.html' # <app>/<model>_<viewtype>.html
context_object_name = 'posts'
ordering = ['-date_posted']
paginate_by = 5
class UserPostListView(ListView):
model = Post
template_name = 'blog/user_posts.html' # <app>/<model>_<viewtype>.html
context_object_name = 'posts'
paginate_by = 5
def get_queryset(self):
# it will get that user form that database if it exist, if user doesn't exist return 404,
# we are also using the User model, so need to import it
# 2nd parameter means that we are getting the username from the url
user = get_object_or_404(User, username=self.kwargs.get('username'))
# showing the posts by that specific user only
return Post.objects.filter(author=user).order_by('-date_posted')
# Looking at individual post
class PostDetailView(DetailView):
model = Post
class PostCreateView(LoginRequiredMixin, CreateView):
model = Post
fields = ['title', 'content']
def form_valid(self, form):
form.instance.author = self.request.user
return super().form_valid(form)
class PostUpdateView(LoginRequiredMixin, UserPassesTestMixin, UpdateView):
model = Post
fields = ['title', 'content']
def form_valid(self, form):
form.instance.author = self.request.user
return super().form_valid(form)
def test_func(self):
post = self.get_object()
if self.request.user == post.author:
return True
return False
class PostDeleteView(LoginRequiredMixin, UserPassesTestMixin, DeleteView):
model = Post
def test_func(self):
post = self.get_object()
if self.request.user == post.author:
return True
return False
def about(request):
return render(request, 'blog/about.html', {'title': 'About'})
def search(request):
if request.method == "POST":
searched = request.POST['searched']
posts = Post.objects.filter(
Q(title__icontains=searched) |
Q(author__username__icontains=searched))
usernames = []
for post in posts:
usernames.append(post.author)
# remove duplicates of username
usernames = list(set(usernames))
context = {'searched': searched, 'posts': posts, 'usernames': usernames}
return render(request, 'blog/search.html', context)
else:
return render(request, 'blog/search.html', {})
Use ForeignKey instead of OneToOneField. Add a related_name:
class Profile(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="profile")
image = models.ImageField(default='default.jpg', upload_to='profile_pics')
in html:
<img class="rounded-circle article-img" src="{{ post.author.profile.image.url }}">
You can write a custom method also.
e.g:
class Post(models.Model):
...
author = models.ForeignKey(User, on_delete=models.CASCADE)
...
def get_owner_pp(self):
return self.author.profile.image.url
in html:
<img class="rounded-circle article-img" src="{{ post.get_owner_pp }}">
Related
I ran into a problem I have questions that are related to items_buy_id , there are also choices that are related to question_id questions
Questions items_buy_id It turns out to connect
And with the choice you will not contact as it should
My models.py
from django.db import models
from datetime import datetime
from phonenumber_field.modelfields import PhoneNumberField
from django_resized import ResizedImageField
from email.policy import default
from django.utils.translation import gettext_lazy
class Items_buy(models.Model):
class Meta:
db_table = 'items_buy'
verbose_name = 'Телефон который покупаем'
verbose_name_plural = 'Телефоны которые покупаем'
image_phone = ResizedImageField(size=[100,100], upload_to='for_sell/',verbose_name='Фотография модели телефона')
model_produkt = models.TextField(max_length=80, verbose_name='Модель продукта ')
text = models.TextField(max_length=500, verbose_name='Текст')
max_prise_iphone = models.FloatField(verbose_name='Максимальная цена telefoha')
image_phone_for_buy_bord = ResizedImageField(size=[100,100],upload_to='for_sell/',verbose_name='Фотография модели телефона ha prodazy')
def __str__(self):
return self.model_produkt
class Question(models.Model):
class Meta:
db_table = 'question'
verbose_name = 'Вопрос к телефону'
verbose_name_plural = 'Вопросы к телефону'
items_buy_id = models.ForeignKey(Items_buy, on_delete=models.RESTRICT)
title = models.CharField(max_length=150,verbose_name='Заголовок вопросa')
question_text =models.TextField(max_length=100, verbose_name='Заголовок вопросa text')
max_prise_qustion = models.FloatField(verbose_name='Максимальная цена')
def __str__(self):
return self.title
class Choice(models.Model):
class Meta:
db_table = 'choice'
verbose_name = 'Выбор ответа'
verbose_name_plural = 'Выбор ответов'
#items_buy_id = models.ForeignKey(Items_buy, on_delete=models.RESTRICT)
question_id = models.ForeignKey(Question, on_delete=models.RESTRICT)
title = models.CharField(max_length=1000, verbose_name='Заголовок выбора')
points = models.FloatField(verbose_name='Цена ответа')
#lock_other = models.BooleanField(default=False, verbose_name='Смотреть другой вариант ответа')
def __str__(self):
return self.title
My urls.py
from django.urls import path, re_path
from . import views
urlpatterns = [
path('',views.home, name ='home'),
path('sell_iphone/', views.sell_iphone, name = 'sell_iphone'),
path('sell_iphone_page/<int:pk>/', views.sell_iphone_page, name= 'sell_iphone_page'),
path("getqestion/<int:pk>/", views.getqestion, name = 'getqestion'),
]
My html
{% load static %}
{% block content %}
<head>
<link rel="stylesheet" href="{% static 'css/qestion.css' %}" type="text/css">
</head>
<body>
{% include 'navbar.html' %}
<div class="bar">
{% for question in test %}
<div class="bar_infor_bar">
<div class="bar_infor_bar_title">{{question.title}} </div>
<div class="wraper_sell_in_line_img_class2_qestion_text">{{question.question_text}}</div>
{% for choiceses in choice %}
<div class="bar_infor_button_nav">
<button class="bar_infor_button">{{choiceses.title}}</button>
</div>
{% endfor %}
</div>
{% endfor %}
</div>
</body>
{% endblock %}
My views.py
from django.shortcuts import render, redirect
from .models import Items_buy, Question, Choice, Answer, Orders
from django.core.paginator import Paginator,PageNotAnInteger,EmptyPage
def home(request):
return render(request, 'home.html')
def sell_iphone(request):
limit = request.GET.get('limit')
if limit == None:
limit = 40
limit = int(limit)
iphone = Items_buy.objects.filter()
count = iphone.count()
page = request.GET.get('page')
paginator = Paginator(iphone, 1)
try:
iphone = paginator.page(page)
except PageNotAnInteger:
page = 1
iphone = paginator.page(page)
except EmptyPage:
page = paginator.num_pages
iphone = paginator.page(page)
#pages = list(range(1, (paginator.num_pages + 1)))
iphone = Items_buy.objects.all()
#iphone = iphone[0:limit]
context = {'iphone':iphone, 'count':count, 'paginator':paginator, }
return render(request, 'sell_iphone.html', context)
def sell_iphone_page(request,pk ):
iphones = Items_buy.objects.filter(id=pk)
#question = Question.objects.all()
context = {'iphones':iphones, }
return render(request, 'sell_iphone_page.html', context)
`def getqestion( request, pk):
test = Question.objects.filter(items_buy_id = pk)
choice = Choice.objects.filter(question_id = pk)
context = {'test':test,'choice':choice}
return render(request, 'getqestion.html', context)`
I'm having a problem with the def getqestion function. I linked the question to the product, but the answer to the question didn't work at all
When using select choice = Choice.objects.filter(question_id = pk)
enter image description here
When using select choice = Choice.objects.all()
enter image description here
When using select choice = Choice.objects.filter(id = pk)
enter image description here
And you need 1.test1 to include: da, net, HY TAKOE
And 1.test2 included: 2,1,3
Thanks in advance to anyone who can suggest how to do this!!!
In my case it helped
views.py
class getqestion(generic.DetailView):
model = Items_buy
template_name = 'getqestion.html'
context_object_name = 'testing'
html
<div>
{% for testings in testing.question_set.all %}
<h1>{{testings.titles}}</h1>
<h3>{{testings.question_text}}</h3>
{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}
{% csrf_token %}
<form action="{% url 'vote' testings.id%}" method="post">
{% for choice in testings.choice_set.all %}
<input type="checkbox" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}">
<label for="choice{{ forloop.counter }}">{{choice.title}}</label>
{% endfor %}
{% endfor %}
</div>
<input type="submit" value="vote">
</form>
I am trying to add some functionality that would allow a reply to the comment and display that reply underneath the comment but after trying everything I am unable to see the
reply being displayed to the comment. There are no errors showing so I can't really figure it out. I am guessing something is not right in the template? Please find the codes below. Hope that is all it requires to get me some help.
MODELS: comment model & reply model
class Comment(models.Model):
"""comments for Post model"""
comment_post = models.ForeignKey(Post, on_delete=models.CASCADE,
related_name='comment_for_post', null=True, default='')
comment_text = models.TextField(null=True)
date_posted = models.DateTimeField(auto_now=True)
def get_absolute_url(self):
"""Reverse the Comment to the url once action
has been taken with primary key to direct back to details page"""
return reverse('posts:post_details', kwargs={'pk': self.pk})
def __str__(self):
return self.comment_text
class Reply(models.Model):
"""add reply to commnets"""
reply_comment = models.ForeignKey(
Comment, on_delete=models.CASCADE, null=True, default='', related_name='comment_reply')
reply_text = models.TextField()
date_posted = models.DateTimeField(auto_now=True)
def __str__(self):
return self.reply_text
VIEWS: reply to comment view
#login_required
def reply_to_comment(request, pk):
comment = get_object_or_404(models.Comment, pk=pk)
if request.method == 'POST':
form = forms.ReplyCommentForm(request.POST)
if form.is_valid():
reply = form.save(commit=False)
reply.reply_comment = comment
reply.save()
return redirect('posts:post_details', pk=comment.pk)
else:
form = forms.ReplyCommentForm()
return render(request, 'posts/reply_comment_form.html', context={'form': form})
URLS:
urlpatterns = [
path('post_list/', views.PostListView.as_view(), name='post_list'),
path('user/<str:username>/', views.UserPostListView.as_view(), name='user_posts'),
path('create/', views.PostCreateView.as_view(), name='create'),
path('details/<int:pk>/', views.PostDetailView.as_view(), name='post_details'),
path('delete/<int:pk>/', views.PostDeleteView.as_view(), name='post_delete'),
path('update/<int:pk>/', views.PostUpdateView.as_view(), name='post_update'),
path('<str:category>/', views.CategoryPostListView.as_view(),
name='category_posts'),
path('posts/<int:pk>/comment', views.add_comment_to_post,
name='post_comment_list'),
path('delete_comment/<int:pk>/',
views.CommentDeleteView.as_view(), name='delete_comment'),
path('comment/<int:pk>/reply/', views.reply_to_comment, name='reply'),
TEMPLATE:
<div class='container'>
{% for reply in comment.comment_reply.all %}
<br>
{% if object.author == user %}
<div class="">
<ul>
<li>
<p >{{reply.reply_text}}</p>
<p class='text-capitalize'>From {{user.username}} on {{comment.date_posted|date:'d-M-y'}}.</p>
</li>
</ul>
</div>
{%else %}
<div class="">
<ul>
<li>
<p >{{reply.reply_text|safe}}</p>
<p class='text-capitalize'>From {{user.username}} on {{comment.date_posted|date:'d-M-y'}}.</p>
</li>
</ul>
{% endif %}
{% endfor %}
</div>
Try to add the code below:
context={'form': form, 'comment': comment}
The page should display a feedback form and links created in the admin panel. Created models:
from django.db import models
class ContactModel(models.Model):
# feedback form
name = models.CharField(max_length=50)
email = models.EmailField()
website = models.URLField()
message = models.TextField(max_length=5000)
create_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return f'{self.name} - {self.email}'
class ContactLink(models.Model):
# links
icon = models.FileField(upload_to='icons/')
name = models.CharField(max_length=200)
def __str__(self):
return self.name
I connected the models to the admin panel:
from django.contrib import admin
from .models import ContactModel, ContactLink
#admin.register(ContactModel)
class ContactModelAdmin(admin.ModelAdmin):
list_display = ['id', 'name', 'email', 'create_at']
list_display_links = ('name',)
admin.site.register(ContactLink)
Everything works correctly, you can create links in the admin panel.
Below views.py:
from django.shortcuts import render
from django.views import View
from .models import ContactLink
class ContactView(View):
def get(self, request):
contacts = ContactLink.objects.all()
form = ContactForm()
return render(request, 'contact/contact.html', {'contact': contacts, 'form': form})
urls.py:
from django.urls import path
from . import views
urlpatterns = [
path('contact/', views.ContactView.as_view(), name='contact'),
path('feedback/', views.CreateContact.as_view(), name='feedback'),
]
I go through the for loop through the code to return links from the admin panel:
#links
<div class="contact__widget">
<ul>
{% for contact in contacts %}
<li>
<img src="{{ contact.icon.url }}">
<span>{{ contact.name }}</span>
</li>
{% endfor %}
</ul>
</div>
#feedback form
<form action="{% url 'feedback' %}" method="post">
{{ form }}
<button type="submit" class="site-btn">Submit</button>
</form>
The Feedback form works fine, but links are not displayed at all on the page... Where could the error be?
Screenshot
The view must reference to the correct variable name. Use contact with an s in:
return render(request, 'contact/contact.html', {'contacts': contacts, 'form': form})
I'm new to python and Flask, I'm having an issue with updating a field entry, I can add 2 fields in a user profile and saves data to their user page, also I'm able to delete that entry, but when trying to update the "Tips" field, it comes back as a 'Bad Request' error; files are:
app.py:
from flask import Flask, render_template, request, redirect, url_for, flash
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField, PasswordField
from flask_sqlalchemy import SQLAlchemy
from forms import RegistrationForm, LoginForm, InstrumentForm, IdeasForm
from werkzeug.urls import url_parse
from werkzeug.security import generate_password_hash, check_password_hash
from wtforms import StringField, SubmitField
from wtforms.validators import ValidationError, DataRequired, Email, EqualTo, Length
from flask_login import LoginManager, UserMixin, current_user, login_user, logout_user, login_required
from flask_bootstrap import Bootstrap
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///Mix_Tips.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config["TEMPLATES_AUTO_RELOAD"] = True
db = SQLAlchemy(app)
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = 'login'
class User(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key= True)
username = db.Column(db.String(15), index =True, unique = True)
email = db.Column(db.String(150), index = True, unique = True)
password_hash = db.Column(db.String(200))
idea = db.relationship('Ideas', backref='author', lazy='dynamic')
def __repr__(self):
return '<User {}>'.format(self.username)
return '<N'
def set_password(self, password):
self.password_hash = generate_password_hash(password)
def check_password_hash(self, password):
return check_password_hash(self.password_hash, password)
class Tips(db.Model):
Instrument = db.Column(db.String(50), primary_key = True)
Frequency_Boost = db.Column(db.String(200), index =True, unique=True)
Frequency_Cut = db.Column(db.String(200), index =True, unique = True)
Advice = db.Column(db.String(500))
class Ideas(db.Model):
id = db.Column(db.Integer, primary_key = True)
Instrument = db.Column(db.String(50))
Tips = db.Column(db.String(200))
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
def __repr__(self):
return '<Tricks {}>'.format(self.Tips)
#app.route('/', methods=["GET", "POST"])
def login():
form = LoginForm()
if form.validate_on_submit():
user = User.query.filter_by(username=form.username.data).first()
if user and user.check_password_hash(form.password.data):
login_user(user, remember=form.remember_me.data)
return redirect(url_for('user', username = form.username.data))
if user is None or not user.check_password_hash(form.password.data):
flash('Invalid username or password')
return render_template('login.html', form=form)
#app.route('/register', methods=["GET", "POST"])
def register():
form = RegistrationForm()
if form.validate_on_submit():
user = User(username=form.username.data, email=form.email.data)
user.set_password(form.password.data)
db.session.add(user)
db.session.commit()
flash('Congratulations, you are now a registered user!')
return redirect(url_for('login'))
return render_template('register.html', title='Register', form=form)
#app.route('/user/<username>', methods=["GET", "POST"])
#login_required
def user(username):
user = current_user
user = User.query.filter_by(username=user.username).first()
idea = Ideas.query.filter_by(user_id=user.id)
if idea is None:
idea = []
form = IdeasForm()
if request.method == 'POST' and form.validate():
New_Idea = Ideas(Instrument = form.Instrument.data, Tips = form.Tips.data, user_id=current_user.id)
db.session.add(New_Idea)
db.session.commit()
print(request.form.get('Tips'))
return render_template('user.html', user=user, form=form, idea=idea)
#app.route('/update/<int:id>', methods=['POST', 'GET'])
def update(id):
tip_to_update = Ideas.query.get_or_404(id)
if request.method == 'POST':
tip_to_update.Tips = request.form['Tips']
db.session.commit()
return redirect(url_for('user', username=current_user))
else:
return render_template('update.html', tip_to_update=tip_to_update)
#app.route('/delete/<int:id>')
def delete(id):
idea_to_delete = Ideas.query.get_or_404(id)
try:
db.session.delete(idea_to_delete)
db.session.commit()
return redirect(url_for('user', username=current_user))
except:
return "Problem Deleting"
#login_manager.user_loader
def load_user(id):
return User.query.get(int(id))
#app.route('/logout')
def logout():
logout_user()
return redirect(url_for('login'))
**user.html:**
{% extends 'base.html' %}
{% block content %}
<center><h1 style="color:rgb(41, 15, 135)">Welcome back {{current_user.username }}!</h1></center>
<center><h2 style="color:rgb(41, 15, 135)">Music Mixing Guide</h2></center>
<h3 style="color:rgb(69, 67, 67)">Add your Instrument and Specific Tips for Mixing below:</h3>
<form action="user" method='POST'>
{{ form.hidden_tag() }}
<p
style="color:rgb(52, 52, 52)">{{form.Instrument.label}} <br>
{{form.Instrument(size=30)}}
</p>
<p
style="color:rgb(52, 52, 52)">{{form.Tips.label}} <br>
{{form.Tips(size=80)}}
</p>
<p> <input class="btn btn-outline-dark" type="submit" value="Add"></p>
</form>
<br>
<h3>Your Music Mixing Tips</h3>
{% for tricks in idea %}
<ol>
<li><p style="color:rgb(41, 15, 135)"> <b><h5>Instrument:</h5></b> {{tricks.Instrument}}</li>
<p style="color:rgb(41, 15, 135)"> <b><h5>Tip:</h5></b> {{tricks.Tips}}
</ol>
<p></p> Update
Delete
<br>
{% endfor %}
<br>
<br>
<br>
Log Out
{% endblock %}
**update.html:**
{% extends 'base.html' %}
{% block content %}
<div class='container'></div>
<h2>Update Mix Tip</h2>
<br>
<form action="/update/{{tip_to_update.id}}" method="POST">
<input type="text" placeholder="Tip" Tips="Tips" class="form-control" value="{{tip_to_update.Tips}}"> <br> <br>
<input type="submit" value="Update" class="btn btn-secondary btn-sm">
</form>
</div>
{% endblock %}
**forms.py**
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, BooleanField, SubmitField, SelectField
from wtforms.validators import ValidationError, DataRequired, Email, EqualTo, Length
from flask_sqlalchemy import SQLAlchemy
class RegistrationForm(FlaskForm):
username=StringField('Username', validators=[DataRequired(), Length(min=4, max=15)])
email=StringField('Email', validators=[DataRequired(), Email(message='Invalid Email'), Length(max=150)])
password=PasswordField('Password', validators=[DataRequired(), Length(min=4, max=150)])
Repeat_password=PasswordField('Repeat Password', validators=[DataRequired(), EqualTo('password')])
submit=SubmitField('Register')
class LoginForm(FlaskForm):
username=StringField('Username', validators=[DataRequired(), Length(min=4, max=15)])
password=PasswordField('Password', validators=[DataRequired(), Length(min=4, max=150)])
remember_me=BooleanField('Remember Me')
submit=SubmitField('Sign In')
class InstrumentForm(FlaskForm):
Instrument= SelectField('Instrument', choices=[('Voice'), ('Acoustic Guitar'), ('Electric Guitar'),
('Bass Guitar'), ('Piano'), ('Bass Drum'), ('Snare Drum'), ('HiHats'), ('Toms'), ('Cymbals'), ('Brass')])
class IdeasForm(FlaskForm):
Instrument = StringField('Instrument')
Tips = StringField('Tips')
submit= SubmitField('Add')
def validate_username(self, username):
user = User.query.filter_by(username=username.data).first()
if user is not None:
raise ValidationError('Please use a different username.')
def validate_email(self, email):
user = User.query.filter_by(email=email.data).first()
if user is not None:
raise ValidationError('Please use a different email address.')
I think it may have something to do with the "request.form['Tips'] line in app.py, but would like to know for sure and how to fix it.
Thanks
welcome mac. I'm not sure the error message, but as far as i can tell you'll need to rework your database models, your relationships to be precised. Here is an example:
class Ideas(db.Model):
id = db.Column(db.Integer, primary_key = True)
instrument = db.Column(db.String(50))
tips = db.relationship("Tips", lazy="dynamic")
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
have a look at the docs: https://flask-sqlalchemy.palletsprojects.com/en/2.x/models/
also i recomment this flask mega tutorial from Miguel Grinberg: https://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-i-hello-world
Thanks for the advice , I finally found out what was wrong , the "tip_to_update.Tips = request.form['Tips']" line in the update route should be "tip_to_update.Tips = form.Tips.data" instead , as I used the Flask Form method of collecting data in my register route, it wasn't accepting the request.form method. I'm still unable to show the data entered in the placeholder when a user wants to update a Tip, it opens the update page with a empty placeholder field to update , but I'd like the text from the entered tip to show , so the user can make a few alterations instead of typing out the whole tip again.
I am using class based views for my Django viewflow project. However I am getting the below error:
Reverse for 'index' not found. 'index' is not a valid view function or pattern name
Here are my classes:
rules/flows.py
class MyFlow(Flow):
"""
My App Flow
"""
process_class = models.MyProcess
start = flow.Start(
views.MyDetailView,
fields=["rule"],
task_title="New Task"
).Permission(
auto_create=True
).Next(this.end)
end = flow.End()
rules/urls.py
rule_urls = FlowViewSet(MyFlow).urls
urlpatterns = [
url(r'^rule/', include(rule_urls, namespace='rule')),
url(r'^(?P<pk>\d+)/mydetail/', MyDetailView.as_view(), {'flow_class': MyFlow, 'flow_task': MyFlow.start}, name='mydetail')
]
rules/models.py
class SubRules(models.Model):
rule_id = models.AutoField(primary_key=True)
src_id = models.IntegerField()
src_description = models.CharField(max_length=160, blank=True)
class Meta:
db_table = 'sub_rules'
class EntRules(models.Model):
rule = models.OneToOneField(SubRules, primary_key=True, on_delete=models.CASCADE)
entitlement_code = models.IntegerField()
rule_approved = models.SmallIntegerField()
rule_approved_datetime = models.DateTimeField(null=True)
class Meta:
db_table = 'ent_rules'
class MyProcess(Process):
entrule = models.ForeignKey(EntRules, blank=True, null=True, on_delete=models.CASCADE)
class Meta:
permissions = (
('approve_ent_rules','Can approve ent_rules')
)
rules/forms.py
class MyDetailForm(forms.ModelForm):
class Meta:
model = EntRules
fields = [
'rule',
'entitlement_code',
]
def __init__(self, *args, **kwargs):
pk = kwargs.pop('rule_id', None)
super(MyDetailForm, self).__init__(*args, **kwargs)
sub_rule = SubRules.objects.get(rule_id=pk)
self.fields['rule'].queryset = sub_rule.objects.filter(rule_id=pk)
rules/views/my_detail.py
class MyDetailView(StartFlowMixin, generic.UpdateView):
model = EntRules
template_name = 'rules/my_detail.html'
form_class = MyDetailForm
layout = Layout(
Fieldset('Rule Details',
Row('rule',),
Row('entitlement_code',),
)
)
def activation_done(self, form):
ent_rule = form.save()
self.activation.process.entrule = ent_rule
super(MyDetailView, self).activation_done(form)
def get_object(self):
return self.activation.process.entrule
def get_form_kwargs(self):
kwargs = super(MyDetailView, self).get_form_kwargs()
pk = int(self.kwargs['pk'])
kwargs['rule_id'] = pk
return kwargs
rules/templates/rules/my_detail.html
{% extends "base.html" %}
{% load material_form %}
{% block content %}
<form method="POST">
{% csrf_token %}
<div class="row">
{% form form=form %} {% endform %}
{{ activation.management_form }}
<div class="right">
<button type="submit" name="_start" class="btn">Submit</button>
</div>
</div>
</form>
{% endblock %}
Can you please advise what could be the issue here ?
I looked at Process Views outside viewflow.frontend
However how do I pass the sub_rule pk "^(?P\d+)" to startview as given in the URL like below ?
class MyFlow(Flow):
start = flow.Start(detail_view_class=MyDetailTaskView)
Please advise.
You can just pass a custom detail view as an argument for flow.Start http://docs.viewflow.io/viewflow_flow_nodes.html#viewflow.flow.StartFunction.detail_view