Giter Site home page Giter Site logo

codingforentrepreneurs / tweetme-2 Goto Github PK

View Code? Open in Web Editor NEW
403.0 23.0 220.0 2.26 MB

Build a twitter-like app in Django, Bootstrap, Javascript, & React.js. Step-by-Step.

Home Page: https://cfe.sh/projects/tweetme-2

Python 48.95% HTML 20.32% CSS 1.13% JavaScript 29.60%
tutorial django javascript bootstrap react reactjs rest-api django-rest-framework twitter tweetme

tweetme-2's Introduction

Tweetme 2

Build a twitter-like app in Django, Bootstrap, Javascript, & React.js. Step-by-Step.

Tweetme 2 Logo

Lesson Code

Lessons 1-5: no significant code added

6 - Updated VS Code Config

7 - Our Roadmap

8 - The Tweets Model

9 - Store Data from Django Model

10 - Intro to URL Routing and Dynamic Routing

11 - Handling Dynamic Routing

12 - Dynamic View into REST API Endpoint

13 - Our First Template

14 - Bootstrap & Django Templates

15 - Tweet List View

16 - Dynamic Load Tweets via JavaScript

17 - Replace HTML Content with JavaScript

18 - Tweets to HTML via JavaScript

19 - Format Tweet Method

20 - Like Button Rendering

21 - Rapid Implement of Bootstrap Theme

22 - Tweet Create Form

23 - Tweet Form by Hand

24 - Successful Form Redirect

25 - Safe URL Redirect

26 - Prevent Form Submit via JavaScript

27 - Sending Form Data via pure JavaScript

28 - Handling Ajax Requests

29 - Serialize Django Model Object

30 - Append New Tweet & Reorder

31 - Handling Form Errors

32 - Rendering the Error Message via Vanilla JavaScript

33 - Users & Tweets

34 - Django Admin

35 - Associate Authenticated User to Object

36 - Permissions & Roadmap

37 - Install Django Rest Framework

38 - Django Forms to Django Rest Framework Serializer

39 - Django Views to Django Rest Framework Views

40 - Permissions and Authentication Classes Decorators for DRF APIs

41 - Delete Tweet API View

42 - Adding a Like Field

43 - Understanding Setting ManyToMayFields

44 - Tweet Action View

45 - JavaScript Tweet Action Handler

46 - CSRF & Client Side Action Buttons

47 - Retweeting Logic

48 - Two Types of Serializers

49 - Internal App Urls

50 - Setting up Tests in Django

51 - Verify or Install Nodejs- no code

52 - Create React App

54 - Ajax lookup via XHR in Reactjs

55 - Handling CORS and Invalid HOST_HEADER in Django

56 - Functional Components in React

57 - Reactjs Action Btn

58 - Using JavaScript Modules

59 - Improved Action Btn

60 - Understanding setState Hook

61 - Handling a Form in React

62 - Pass from Parent Component to Child with useEffect

63 - Adjust the React Render Process

64 - React Rendered by Django

65 - Render React App via Any Django Template

66 - A Better XHR Lookup

67 - Create Tweet in React

68 - Dev Authentication

69 - Handling New Tweet

70 - API Methods in React

71 - Tweet Action Btn

72 - Rendering the ReTweet

73 - Improving the Tweet Action Button

74 - Prepending Dynamic Retweets

75 - Set Data Props on ReactDOM Render

76 - Limit List View by Username

77 - Rendering Limited Tweet List by Username

78 - Tweets Module Clean Up

79 - Lookup & Render & Embed Individual Tweets

80 - Linking Individual Tweets

81 - Build and Use On Django

82 - Clean Up API Urls and Views

83 - Login Required Redirect

84 - Authentication & Registration

85 - User Profiles

86 - Handling Profile Does Not Exist

87 - Signals to Create Profile Objects

88 - Save 2 Models in 1 Form and 1 View

89 - ManyToManyField and Reverse Relations

90 - Followers and Following

91 - Follow Button Logic and Endpoint

92 - Profile Following Unit Tests

93 - User Feed including Following

94 - More Effecient Backend Lookups and Custom Model Managers

95 - More Efficient List Views with Pagination

96 - User Profile Serializer

97 - Handling our New List View Response

98 - Handling Pagination in React

99 - Display User Within Tweet

100 - Display Tweet User Details

101 - Feed View Component

102 - Build for the Feed

103 - User Profile API Detail

104 - Passing the Request to Serializers

105 - Render Profile Badge Component

106 - The Follow Button

107 - Removing Redundant Profile View

108 - Display Follower Count with Numeraljs

109 - FInal Build

110 - Thank you and next steps no code

Next steps:

  • Large File Uploads for Images ~ Dive into AWS
  • Notifications
  • Direct Messages / Private Inboxes ~ Chat x Channels
  • Explore -> parse & filter for hashtags

tweetme-2's People

Contributors

codingforentrepreneurs avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

tweetme-2's Issues

🔴please help me after step 06:23:07 64. React Rendered by Django , when I update reactjs and go to localhost:8000 I don't see any changes.!!!

Note, I'm musing react with tsx (typescript)
my index.tsx file

import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
const getelem = document.getElementById("root");
getelem && ReactDOM.render(<App />, getelem);

reportWebVitals();

my templaes/react.html file has the same code that i copied from build/index
and I did all the other steps.
see my repo

Question About Designing Methods of This app

Hi , I have a question about your approach of design and implementing this application
as we see , you are reactifying django and mix these together but another approach to do this and avoid making SPAs, its to use Frameworks like Next.js , whats your idea about these ?
do u suggest to do this like yourself or we can use those frameworks like nextjs too ?!
does this approach have advantages over others ?
I would be happy to know your opinion
Thank You !

An error about login and rederect

The project is great but I found a problem. I clone this projects and then I run the project. I open the url http://127.0.0.1:8000. When I want to click the button Like then it redirect me to login page. I register and then login But it do not redirect me to the home page . and when I try to open http://127.0.0.1:8000 it redirect me to the login page!!!! I can not open the home page anymore. I try to logout ,then I can open the home page but I still can not to login. Why that happened? 🐛

development server has disconnected

I started the 68. section - Dev Authentication and was about to finish, but the problem was I couldn't tweet like him in the video. I began to look for mistakes and saw that my AUTHENTICATION_CLASSES were named AUTHENTICATED_CLASSES, so I changed the name in my settings but then all the tweets were gone and just the tweet section popped up. A long time I searched for other errors but I couldn't find them and I didn`t want to start allover again so I began to copy the scripts in my project. Of course I made sure that I didn't change important settings or other things. The problem after this was: nothing is rightnow on my react-website and if I look in my console there is the error message:
The development server has disconnected.
Refresh the page if necessary.
[HMR] Waiting for update signal from WDS...
I would be super thankful if somebody could help me.

API Test Case issue (Response Content-Type) with Solution

def test_follow_api_endpoint(self): client = self.get_client() response = client.post(f'/api/profiles/{self.userb.username}/follow', {'action': 'follow'}) count = response.json().get('count') self.assertEqual(count, 1)

Response Content-Type is returned as text/html instead of application/json

Solution:

response = client.post(f'/api/profiles/{self.userb.username}/follow',
{'action': 'follow'}, format='json')

"detail": "JSON parse error - Expecting value: line 1 column 1 (char 0)"

I made some changes to the view and the serializer. Now, when I go to 'api/tweets/create/ and I write a new tweet in the Content post I got and error "detail": "JSON parse error - Expecting value: line 1 column 1 (char 0)"
serlizers.py

from rest_framework import serializers
from .models import Tweet


class TweetActionsSerlizer(serializers.Serializer):
    id = serializers.IntegerField()
    action = serializers.CharField()
    content = serializers.CharField(allow_blank=True, required=False)

    def validate_action(self, value):
        # lower = lower case letter.
        # strip = drop spaces for example "like ".strip() = "like"
        value = value.lower().strip()
        if not value in ['like', 'unlike', 'retweet']:
            raise serializers.ValidationError("this is not avalid action")
        return value


class CreateTweeSerializers(serializers.ModelSerializer):

    class Meta:
        model = Tweet
        fields = ['id', 'content', 'like']

    # def get_likes(self, obj):
        # return obj.like.count()
        # this convert the array of users ids wholiekd to the number of likes

    def validate_content(self, value):
        if len(value) > 200:
            raise serializers.ValidationError("This Tweet is too long")
        return value


class TweeSerializers(serializers.ModelSerializer):
    # like = serializers.SerializerMethodField(read_only=True)
    # if the is no is_retweet @property function in models  you will nedd this line.
    # is_retweet = serializers.SerializerMethodField(read_only=True)
    # content = serializers.SerializerMethodField(read_only=True)
    # this will retrun the data of parents.
    # http://127.0.0.1:8000/posts/ parent:{id,content,like}
    parent = CreateTweeSerializers(read_only=True)

    class Meta:
        model = Tweet
        fields = ['user', 'id', 'content', 'like',
                  'is_retweet', 'parent', ]  # 'timestamp']

    # def get_content(self, obj):
    #     content = obj.content
    #     # if th it is a retweet then its content will = the content of the parent.
    #     # this is to make sure that the already existed tweets will have the content of their parents.
    #     if obj.is_retweet:
    #         content = obj.parent.content
    #     return content

settings.py

from pathlib import Path
import os
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent


# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.1/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = '6)ej64kx92vba7!6tq76^k0smwy)$t5z1m$q6@tn0gxvd58cl9'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = []


# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django.contrib.sites',
    'allauth',
    'allauth.account',
    'allauth.socialaccount',
    'allauth.socialaccount.providers.google',
    'social',
    'rest_framework'


]
SITE_ID = 1


MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
LOGIN_URL = '/accounts/login/'
ROOT_URLCONF = 'vertualizor.urls'
ALLOWED_HOSTS = ['127.0.0.1', 'mydomain.com']

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, "templates")],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

WSGI_APPLICATION = 'vertualizor.wsgi.application'


# Database
# https://docs.djangoproject.com/en/3.1/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
    }
}
AUTHENTICATION_BACKENDS = [

    # Needed to login by username in Django admin, regardless of allauth
    'django.contrib.auth.backends.ModelBackend',

    # allauth specific authentication methods, such as login by e-mail
    'allauth.account.auth_backends.AuthenticationBackend',

]

# Password validation
# https://docs.djangoproject.com/en/3.1/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]


# Internationalization
# https://docs.djangoproject.com/en/3.1/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.1/howto/static-files/

STATIC_URL = '/static/'
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'

DEFAULT_RENDERER_CLASSES = [
    'rest_framework.renderers.JSONRenderer',
]

if DEBUG:
    DEFAULT_RENDERER_CLASSES += [
        'rest_framework.renderers.BrowsableAPIRenderer',
    ]
REST_FRAMEWORK = {

    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework.authentication.SessionAuthentication'
    ],
    'DEFAULT_RENDERER_CLASSES': DEFAULT_RENDERER_CLASSES
}

views.py

from django.shortcuts import render, redirect
from .models import Tweet
from django.utils.http import is_safe_url
from .serializers import CreateTweeSerializers, TweeSerializers, TweetActionsSerlizer
from rest_framework.response import Response
from rest_framework.decorators import api_view, authentication_classes, permission_classes
from rest_framework.permissions import IsAuthenticated
from rest_framework.authentication import SessionAuthentication
# this woll make POST request work and re-render the new posts.


@api_view(["POST"])
# @authentication_classes([SessionAuthentication,MyCustomAuth])
@permission_classes([IsAuthenticated])
def post_create_view(request, *args, **kwargs):
    serializer = CreateTweeSerializers(data=request.POST)
    # raise_exception= if form.error reutnr error and status400
    if serializer.is_valid(raise_exception=True):
        serializer.save(user=request.user)
        return Response(serializer.data, status=201)
    return Response({}, status=400)


def home_view(request, *args, **kwards):
    return render(request, 'pages/home.html', context={}, status=200)


@api_view(["GET"])
def post_view(request, postId, *args, **kwards):
    qs = Tweet.objects.filter(id=postId)
    if not qs.exists():
        return Response({}, status=404)
    return Response(TweeSerializers(qs.first()).data, status=200)


@api_view(["DELETE", 'POST'])
@permission_classes([IsAuthenticated])
def post_delete_view(request, postId, *args, **kwards):
    qs = Tweet.objects.filter(id=postId)
    if not qs.exists():
        return Response({}, status=404)
    qs = qs.filter(user=request.user)
    if not qs.exists():
        return Response({"message": 'you cant delete this Post'}, status=401)
    obj = qs.first()
    obj.delete()
    return Response({'Message': "post removed"}, status=200)


@api_view(["GET"])
def posts_list_view(request, *args, **kwards):
    qs = Tweet.objects.all()
    serializer = TweeSerializers(qs, many=True)
    return Response(serializer.data)


@api_view(['POST'])
@permission_classes([IsAuthenticated])
def post_actions_view(request, *args, **kwards):
    '''
    actions = like,unlike,retweet
    '''
    # i dont understand how request.POST will send the id and the action type to the serlizer?
    # data=request.POST was a mistake
    serlizer = TweetActionsSerlizer(data=request.data)
    print(request.data)
    if serlizer.is_valid(raise_exception=True):
        data = serlizer.validated_data
        post_id = data.get('id')
        action = data.get('action')
        # you must serlize data to the get them.
        content = data.get('content')
    qs = Tweet.objects.filter(id=post_id)
    if not qs.exists():
        return Response({}, status=404)
    obj = qs.first()
    if action == 'like':
        obj.like.add(request.user)
        return Response(serlizer.data, status=200)
    elif action == 'unlike':
        obj.like.remove(request.user)
    elif action == 'retweet':
        newTwee = Tweet.objects.create(
            user=request.user, parent=obj, content=content)
        serlizer = TweeSerializers(newTwee)
        return Response(serlizer.data, status=201)

    return Response({}, status=200)

tweets.tests double function test_tweet_list()

def test_tweet_list(self):
and
def test_tweet_list(self):

Hello, thanks so much for this course. But I noticed a strange thing with the function test_tweet_list() in the class TweetTestCase().

Also, I had problems with ids for test objects and I changed all functions for tests without using ids. It is ok? For example test_action_like():

def test_action_like(self):
        client = self.get_client()
        tweet = Tweet.objects.filter(user=self.user).first()
        response = client.post("/api/tweets/action/", {"id": tweet.id, "action": "like"})
        self.assertEqual(response.status_code, 200)
        like_count = response.json().get("likes")
        self.assertEqual(like_count, 1)

Bug to login with accounts/view.py

08:46:42 - 84. Authentication & Registration

I follow all the video and i haven't a mistake but after tutorial, i have an error :

"AnonymousUser" object has no attribute '_meta'
hfioezofjejfze

Missiong 26. Prevent Form Submit via JavaScript commit

Hello, thank you for this great tutorial! The commits are of the same sequence of the video, they are so organised and clear! Thank you for the efforts.

But I just found that the 26. Prevent Form Submit via JavaScript part is missing in the commits, could you please add it? This way I can have a glance of total changement in a part, no need to re-watch the video.

Thank you :)

CORS headers issue

Hello!

I was working through the project and everything worked just fine, but at the step of adding dev rest api authentication CORS header broke.
Access to XMLHttpRequest at 'http://localhost:8000/api/tweets/' from origin 'http://127.0.0.1:3000' has been blocked by CORS policy: Request header field http_x_requested_with is not allowed by Access-Control-Allow-Headers in preflight response.
It doesn't work both with the localhost and 127.0.0.1
I even dowloaded the full application of this step and it didn't work either.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.