Python Daily
2.57K subscribers
1.48K photos
53 videos
2 files
38.9K links
Daily Python News
Question, Tips and Tricks, Best Practices on Python Programming Language
Find more reddit channels over at @r_channels
Download Telegram
Best practices for letting user delete entries in blog-like page?

I have a simple project working well [(it is the learning log app from Python Crash Course)](https://github.com/ehmatthes/pcc/tree/master/chapter_20). On one page it shows a list of editable entries the user has written about a topic, basically a minor variant on your standard blog starter project. This page listing all the entries of a topic is `topic.html`. I want to give the user the ability to delete the individual entries associated with a topic.

Currently the view for the topic looks like this:

@login_required
def topic(request, topic_id):
"""Show a single topic and all its entries"""
topic = get_object_or_404(Topic, id = topic_id)
#Make sure the topic belongs to the current user
check_topic_owner(request, topic)
entries = topic.entry_set.order_by('-date_added')
context = {'topic': topic, 'entries': entries}
return render(request, 'learning_logs/topic.html', context)

Note that `learning_logs/topic.html` is a pretty standard template that displays all the entries associated with the given topic.

I want to add the ability of the user to delete an entry for the topic. Is the right way to do that to just make a new view (something like 'delete_entry') that takes in the entry_id as an input, and then just runs `delete()` before redirecting back to `topic.html`?

I like this idea because it would be very simple and relatively easy, but OTOH I want to follow best practice. E.g., should I be using the `DeleteView` class? I haven't found much on this topic online, unfortunately, in any of the tutorials I've been using. The two things I've found that frankly I don't really understand:
- https://stackoverflow.com/questions/5531258/example-of-django-class-based-deleteview
- https://www.reddit.com/r/django/comments/38p683/how_are_delete_buttons_along_with_saveedit/

I have never used class-based views or generic views. Should I go back to the drawing board with generic/class-based views and learn about that, and implement the DeleteView class to handle this?


/r/django
https://redd.it/73n71f
f class, which holds the data variables declared in class and the **member functions work on these objects**. Please make a comment if you do not understand, I will try to explain.


`def authenticate():` defines a function which will try to authenticate the bot to Reddit. This is where PRAW comes into play as it provides us methods to do this. Remember we created a *praw.ini* file earlier. It is a configuration file that stores authentication credentials, so that you just call it whenever needed.


Next, we pass authentication parameters to `praw.Reddit()`. Here `explainbot` refers to the credentials in the configuration file, and `user_agent` is a descriptive string about your script/bot. This returns a [Reddit instance](https://praw.readthedocs.io/en/latest/code_overview/reddit_instance.html), which we assign to the variable `reddit`, and use this variable whenever we wish to authenticate.


Next up, we make a print statement to see who is getting authenticated i.e. the name. The `user` class in PRAW provides methods for the currently authenticated user. We call the method `me()` on `user` and then call it on the variable holding the Reddit instance for authentication, which in our case is `reddit`. So the statement becomes `reddit.user.me()`. We just use some [formatting in python](https://pyformat.info/) to print it.


Finally we `return` the variable `reddit`. Now i can use this `authenticate()` function in my program by calling it when I need it, and it will give me the variable `reddit`, which stores the Reddit instance.

------------------------------

**Important note 1:** Why did I create a function? It is because creating functions makes us easy to manage out code. We write separate functions for separate features of the program, and call them wherever needed. This breaks the code into manageable chunks, which makes it easy to read, modify and debug.

------------------------------

##Section 3 - Scraping


https://gist.github.com/aydwi/8ff90e7b0628b07ccd550d91d30024cb


Next up is the function `def fetchdata(url)`. Notice how this function takes a parameter `url`. We pass this parameter whenever we call this function. The purpose of this function is to scrape/gather the data from the web, in order to post an explanation.


**Now scraping is not a very reliable process**, but sometimes we just have to do it. We go to a website, go through it's HTML source, and extract the text, links etc. that we want. Here we use **[Requests](http://docs.python-requests.org/en/master/user/quickstart/#make-a-request)** library to make a web request, and **[Beautiful Soup](https://www.crummy.com/software/BeautifulSoup/bs4/doc/)** to extract the data.


`r = requests.get(url)` gives a Response object called `r`. We can get all the information we need from this object. Then we call the method `content` on `r`, and pass it to `soup = BeautifulSoup(r.content, 'html.parser')`, which gives us a `soup` object with which we can retrieve elements of a web page. Read more [here](https://www.crummy.com/software/BeautifulSoup/bs4/doc/).


Now what happens depends on what are you scraping. Every website has different type of content, and you should go through the HTML to see how can you retrieve what you want. In my case http://explainxkcd.com has it's explanation inside the first few `<p>` tags, so I look for the first `<p>` tag by `tag = soup.find('p')`. Also, immediately after the explanation ends, `<h2>` tag follows, so I know where to stop. Now take a look here-

while True:
if isinstance(tag, bs4.element.Tag):
if (tag.name == 'h2'):
break
if (tag.name == 'h3'):
tag = tag.nextSibling
else:
data = data + '\n' + tag.text
tag = tag.nextSibling
else:
tag = tag.nextSibling

I continue to look through the tags, and store textual data in a `string` named `data` and move to the next tag. I `break` the process if I encounter `<h2>` because I know that is where explanation ends. The code depends on the structure of
Flask program giving module not found

Im building a python web application with flask and uWSGI following this lovely guide https://www.digitalocean.com/community/tutorials/how-to-serve-flask-applications-with-uwsgi-and-nginx-on-centos-7 and it worked marvels, the basic hello does indeed appear in the website hen loaded. I have installed every single module and dependency in the project file. Im trying now to build on the working script and I now my init.py file looks like this:


from flask import Flask
import pylab as pl
import numpy as np
import pandas as pd

from sklearn import svm
from sklearn import tree
import matplotlib.pyplot as plt
from sklearn import linear_model
from sklearn.pipeline import Pipeline
from sklearn.metrics import confusion_matrix
from sklearn.naive_bayes import MultinomialNB
from sklearn.linear_model import SGDClassifier
from mlxtend.plotting import plot_decision_regions
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfTransformer

app = Flask(__name__)

@app.route("/")


def hello():
data = pd.read_csv('test1.csv', error_bad_lines=False, delimiter=',')
numpy_array = data.as_matrix()
#print numpy_array

#text in column 1, classifier in column 2.
X = numpy_array[:,0]
Y = numpy_array[:,1]
Y=Y.astype(np.str)

#divide the test set and set the variable to their correct label/text
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.4, random_state=42)

#MultinomialNB
text_clf = Pipeline([('vect', CountVectorizer(stop_words='english')), ('tfidf', TfidfTransformer()),('clf', MultinomialNB()),])

text_clf = text_clf.fit(X_train.astype('U'),Y_train.astype('U'))
predicted = text_clf.predict(X_test)
# print the actual accuracy
print "MNB accuracy: ", np.mean(predicted == Y_test)

#make the confusion matrix
y_actu = pd.Series(Y_test, name='Actual')
y_pred = pd.Series(predicted, name='Predicted')
df_confusion = pd.crosstab(y_actu, y_pred)
print df_confusion

print"-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------$

#SVM
vect = CountVectorizer(min_df=0., max_df=1.0)
X = vect.fit_transform(X_train.astype('U'))
min_frequency = 22

text_clf_svm = Pipeline([('vect', CountVectorizer(min_df=min_frequency, stop_words='english')), ('tfidf', TfidfTransformer()),('clf-svm', SGDClassifier(loss='hinge', penalty='l2', alpha=1e-03, n_iter=1000, random_state=21))])

text_clf_svm = text_clf_svm.fit(X_train.astype('U'),Y_train.astype('U'))
predicted_svm = text_clf_svm.predict(X_test)
# print the actual accuracy
print "svm accuracy: ", np.mean(predicted_svm == Y_test)

#make the confusion matrix
y_actu = pd.Series(Y_test, name='Actual')
y_pred = pd.Series(predicted_svm, name='Predicted')
df_confusion = pd.crosstab(y_actu, y_pred)

print df_confusion


if __name__ == "__main__":
app.run()
'''''

All is good with this as far as im concerned made sure to install all dependencies and module sin the folder from which im running the code. but when I run it I get the following error

'''''
[root@python-political-bias-app fyp]# semodule -i mynginx.pp
[root@python-political-bias-app fyp]# env/bin/uwsgi --socket 127.0.0.1:8080 -w WSGI:app &
[1] 1710
[root@python-political-bias-app fyp]# *** Starting uWSGI 2.0.15 (64bit) on [Wed Feb 7 01:16:21 2018] ***
compiled with version: 4.8.5 20150623 (Red Hat 4.8.5-16) on 06 February 2018 20:03:13
os: Linux-3.10.0-693.17.1.el7.x86_64 #1 SMP Thu Jan 25 20:13:58 UTC 2018
nodename: python-political-bias-app
machine: x86_64
clock source: unix
pcre jit disabled
detected number of CPU cores: 1
current working dir
Does anyone follow the Fat Model, Skinny View design pattern in real-world projects?

We're currently dealing with some very thick views at work (think legacy startup code, lol), and I'd like to establish a convention to avoid this in the future. I've found a few resources that recommend encapsulating business logic in your models.

While I'm considering the 'Fat models, skinny views' approach, I'm also curious about any potential pitfalls or challenges that might come with it.

Could you share any insights or experiences in this regard?

Thanks in advance!

References:
- Official docs: https://docs.djangoproject.com/en/5.0/misc/design-philosophies/#include-all-relevant-domain-logic
- Best practices site I found: https://django-best-practices.readthedocs.io/en/latest/applications.html#make-em-fat

/r/django
https://redd.it/1dlxhg3