Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
158 views
in Technique[技术] by (71.8m points)

Flutter/ Django rest API calls

So I am trying to connect my Django rest framework backend with my Flutter UI and I'm having some issues. I currently only have a register, login and logout links that are fully function on the backend, I tested them in postman and they work. But when I try to connect to them through my Flutter app I get a 404 error saying that it couldn't find the API link. I can't seem to figure out what the problem is and I've been trying at it for a couple of days now lol any help is help.

Here is my code:


DRF Backend:


views.py:

from rest_framework import status
from rest_framework.response import Response
from rest_framework.decorators import api_view, authentication_classes, permission_classes
from rest_framework.authentication import TokenAuthentication
from rest_framework.permissions import IsAuthenticated, AllowAny
from .serializers import RegistrationSerializer
from rest_framework.authtoken.models import Token

@api_view(['POST'])
@permission_classes([AllowAny])
def registration_view(request):
    print("got here first")

    if request.method == 'POST':
        print("got here")
        serializer = RegistrationSerializer(data=request.data)
        data = {}
        if serializer.is_valid():
            print("got valid")
            user = serializer.save()
            data['response'] = "succesfully registered a new user."
            data['email'] = user.email
            data['username'] = user.username
            token = Token.objects.get(user=user).key
            data['token'] = token
        else:
            data = serializer.errors
        return Response(data)

@api_view(['POST'])
@permission_classes([IsAuthenticated])
def logout_view(request):
    cToken = Token.objects.get(user=request.user)
    cToken.delete()
    return Response("Succesfully logged out")

urls.py:

from django.urls import path
from .views import registration_view, logout_view
from rest_framework.authtoken.views import obtain_auth_token
# from rest_framework.permissions import IsAuthenticated


app_name = "backApp"

urlpatterns = [
    path('register', registration_view, name="register"),
    path('login', obtain_auth_token, name="login"),
    path('logout', logout_view, name="logout")
]

serializers.py:

from rest_framework import serializers

from backApp.models import User

class RegistrationSerializer(serializers.ModelSerializer):

    password2 = serializers.CharField(style={'input_type': 'password'}, write_only=True)

    class Meta:
        model = User
        fields = ['email', 'username', 'password', 'password2']
        extra_kwargs = {
            'password': {'write_only': True}
        }

    def save(self):
        user = User(
            email=self.validated_data['email'],
            username=self.validated_data['username'],
        )
        password = self.validated_data['password']
        password2 = self.validated_data['password2']

        if password != password2:
            raise serializers.ValidationError({'password': 'Passwords must match.'})
        user.set_password(password)
        user.save()
        return user

models.py:

from django.db import models
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
from django.conf import settings
from django.db.models.signals import post_save
from django.dispatch import receiver
from rest_framework.authtoken.models import Token

class MyUserManager(BaseUserManager):
    def create_user(self, email, username, first_name, last_name,password=None):
        if not email:
            raise ValueError("Users must have an email address.")
        if not username:
            raise ValueError("Users must have a username.")
        if not first_name:
            raise ValueError("Users must have a first name.")
        if not last_name:
            raise ValueError("Users must have a last name.")

        user = self.model(
            email=self.normalize_email(email),
            username=username,
            first_name=first_name,
            last_name=last_name
        )

        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_superuser(self, email, username, password, first_name, last_name):
        user = self.create_user(
            email=self.normalize_email(email),
            username=username,
            password=password,
            first_name=first_name,
            last_name=last_name
        )
        user.is_admin = True
        user.is_staff = True
        user.is_superuser = True
        user.save(using=self._db)
        return user


class User(AbstractBaseUser):
    email = models.EmailField(verbose_name="email", max_length=80, unique=True)
    first_name = models.CharField(verbose_name="first name", max_length=80)
    last_name = models.CharField(verbose_name="last name", max_length=80)
    tap_coins = models.IntegerField(default=0)
    username = models.CharField(max_length=80, unique=True)
    date_joined = models.DateTimeField(verbose_name="date joined", auto_now_add=True)
    last_login = models.DateTimeField(verbose_name="last login", auto_now=True)
    is_admin = models.BooleanField(default=False)
    is_active = models.BooleanField(default=True)
    is_staff = models.BooleanField(default=False)
    is_superuser = models.BooleanField(default=False)

    USERNAME_FIELD = "email"
    REQUIRED_FIELDS = ["username", "first_name", "last_name"]

    objects = MyUserManager()

    def __str__(self):
        return self.email

    def has_perm(self, perm, obj=None):
        return self.is_admin

    def has_module_perms(self, app_label):
        return True

@receiver(post_save, sender=settings.AUTH_USER_MODEL)
def create_auth_token(sender, instance=None, created=False, **kwargs):
    if created:
        Token.objects.create(user=instance)

Flutter:


main.dart:

import 'package:TapCoinsApp/api/api.dart';
import 'package:TapCoinsApp/screens/profile.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import './screens/register.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        ChangeNotifierProvider(create: (context) => UserProvider()),
        // ChangeNotifierProvider(create: (context) => BankProvider())
      ],
      child: MaterialApp(
        title: 'Flutter Demo',
        theme: ThemeData(
          primarySwatch: Colors.blue,
          visualDensity: VisualDensity.adaptivePlatformDensity,
        ),
        home: HomePage(),
      ),
    );
  }
}

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    final userP = Provider.of<UserProvider>(context);
    // final bankP = Provider.of<BankProvider>(context);
    int prizeCoins = 0;
    int coinsTapped = 0;
    return MaterialApp(
      home: SafeArea(
        child: DefaultTabController(
          length: 2,
          child: Scaffold(
            appBar: TabBar(
              tabs: [
                Tab(icon: new Icon(Icons.home)),
                Tab(icon: new Icon(Icons.person_outline_rounded)),
              ],
              labelColor: Colors.red,
              unselectedLabelColor: Colors.yellow,
              indicatorSize: TabBarIndicatorSize.label,
              indicatorPadding: EdgeInsets.all(5.0),
              indicatorColor: Colors.red,
            ),
            backgroundColor: Colors.purple,
            body: Stack(
              children: <Widget>[
                TabBarView(children: [
                  new Scaffold(
                    backgroundColor: Colors.purple,
                    floatingActionButton: FloatingActionButton(
                      onPressed: () {
                        Navigator.of(context).push(MaterialPageRoute(
                            builder: (ctx) => RegisterUser()));
                      },
                    ),
                  ),
                  ProfilePage(),
                ]),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

register.dart:

import 'package:TapCoinsApp/api/api.dart';
import 'package:TapCoinsApp/models/user.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

class RegisterUser extends StatefulWidget {
  @override
  _RegisterUserState createState() => _RegisterUserState();
}

class _RegisterUserState extends State<RegisterUser> {
  final userFirstNameController = TextEditingController();

  final userLastNameController = TextEditingController();

  final userEmailController = TextEditingController();

  final userUserNameController = TextEditingController();

  final userPasswordController = TextEditingController();

  final userPassword2Controller = TextEditingController();

  void _onRegister() {
    final String firstVal = userFirstNameController.text;
    final String lastVal = userLastNameController.text;
    final String emailVal = userEmailController.text;
    final String userVal = userUserNameController.text;
    final String passwordVal = userPasswordController.text;
    final String password2Val = userPassword2Controller.text;

    if (firstVal.isNotEmpty &&
        lastVal.isNotEmpty &&
        emailVal.isNotEmpty &&
        userVal.isNotEmpty &&
        passwordVal.isNotEmpty &&
        password2Val.isNotEmpty) {
      final User user = User(
          firstName: firstVal,
          lastName: lastVal,
          email: emailVal,
          userName: userVal,
          password: passwordVal,
          password2: password2Val);
      print(user);
      Provider.of<UserProvider>(context, listen: false).registerUser(user);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(title: Text("Register!")),
        body: ListView(
          children: [
            Container(
                child: Column(
              children: [
                TextField(
                  controller: userFirstNameController,
                  decoration: InputDecoration(labelText: "First Name: "),
                ),
                TextField(
                    controller: userLastNameController,
                    decoration: InputDecoration(labelText: "Last Name: ")),
                TextField(
                    controller: userEmailController,
                    decoration: InputDecoration(labelText: "Email: ")),
                TextField(
                    controller: userUserNameController,
                    decoration: InputDecoration(labelText: "Username: ")),
                TextField(
                    controller: userPasswordController,
                    decoration: InputDecoration(labelText: "Password: ")),
                TextField(
                    controller: userPassword2Controller,
                    decoration:
                        InputDecoration(labelText: "Confirm Pas

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I think that you have tested the API on your personal machine. You have to publish your API and database on some online server or web, so you can access it in the mobile app.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...