Reputation: 639
I'm using Djangorestframework (DRF) as backend and flutter with Getx package as frontend. in the DB i have a model that contains image and file fields.
in my models.py:
class Member(models.Model):
FATHER = 0
MOTHER = 1
SON = 2
DAUGHTER = 3
FAMILY_MEMBER = (
(FATHER, _("Father")),
(MOTHER, _("Mother")),
(SON, _("Son")),
(DAUGHTER, _("Daughter")),
)
family = models.ForeignKey(Family, on_delete=models.CASCADE)
name = models.CharField(_("Name"), max_length=255)
relation = models.PositiveSmallIntegerField(
_("Role"), choices=FAMILY_MEMBER, default=FATHER
)
contact = models.CharField(_("Contact"), max_length=12)
nid = models.FileField(_("National ID"), upload_to="ids/") # PDF
face_img = models.ImageField(_("Face Image"), upload_to="faces/") # Image
age = models.PositiveIntegerField(_("Age"), default = 0)
education = models.TextField(_("Education"), blank=True, null=True)
health = models.TextField(_("Health"), blank=True, null=True)
income = models.DecimalField(_("Income"), max_digits=10, decimal_places=2, default=0.00)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
in my models.dart:
class Member {
final int? pk;
final String name;
final int family;
final int relation;
final String? contact;
final String nid;
final String? faceImg;
final int age;
final String? education;
final double income;
final String? health;
final DateTime? createdAt;
final DateTime? updatedAt;
Member({
this.pk,
required this.name,
required this.family,
required this.relation,
this.contact,
required this.nid,
this.faceImg,
required this.age,
this.education,
this.health,
required this.income,
this.createdAt,
this.updatedAt,
});
factory Member.fromJson(Map<String, dynamic> json) => Member(
pk: json["id"] as int?,
name: json["name"] as String,
family: json["family"] as int,
relation: json["relation"] as int,
contact: json["contact"] as String? ?? '',
nid: json["nid"] as String,
faceImg: json["face_img"] as String?,
age: json["age"] as int,
education: json["education"] as String? ?? '',
health: json["health"] as String? ?? '',
income: json["income"] as double? ?? 0.0,
createdAt: json['created_at'] != null
? DateTime.parse(json['created_at'])
: null,
updatedAt: json['updated_at'] != null
? DateTime.parse(json['updated_at'])
: null,
);
Map<String, dynamic> toJson() => <String, dynamic>{
"id": pk,
"name": name,
"family": family,
"relation": relation,
"contact": contact,
"nid": nid,
"face_img": faceImg,
"age": age,
"education": education,
"health": health,
"income": income.toString(),
"created_at": createdAt?.toIso8601String(),
"updated_at": updatedAt?.toIso8601String(),
};
}
the list in screen that handle CRUD, member_screen.dart:
Obx(() {
if (controller.isLoading.value) {
return const Center(
child: Padding(
padding: EdgeInsets.all(8.0),
child: CircularProgressIndicator(
semanticsLabel: "Loading",
),
),
);
} else if (controller.members.isEmpty) {
return const Center(child: Text('No members found'));
} else {
return ListView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemCount: controller.members.length,
itemBuilder: (context, index) {
final member = controller.members[index];
return ListTile(
title: Text('Member ${member.pk}'),
subtitle: Text(member.name),
leading: member.faceImg != null
? CircleAvatar(
backgroundImage: NetworkImage(member.faceImg!),
)
: const CircleAvatar(
child: Icon(Icons.person),
),
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: [
IconButton(
color: Colors.green,
icon: const Icon(Icons.edit),
onPressed: () {
// Edit member
Get.bottomSheet(
MemberForm(
key: UniqueKey(),
member: member,
),
backgroundColor: Colors.white,
isScrollControlled: true,
);
},
),
IconButton(
color: Colors.red,
icon: const Icon(Icons.delete),
onPressed: () {
// Delete member
Get.defaultDialog(
title: "Delete Member",
middleText:
"Are you sure you want to delete this member?",
textCancel: "Cancel",
textConfirm: "Delete",
confirmTextColor: Colors.white,
onConfirm: () {
if (member.pk != null) {
controller.deleteMember(member.pk!);
}
Get.back();
},
);
},
),
],
),
onTap: () {
Get.bottomSheet(
Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Member ${member.pk} Details',
style: const TextStyle(
fontSize: 24, fontWeight: FontWeight.bold)),
const SizedBox(height: 16),
Text('Name: ${member.name}',
style: const TextStyle(fontSize: 18)),
const SizedBox(height: 8),
Text('Family: ${member.family}',
style: const TextStyle(fontSize: 18)),
const SizedBox(height: 8),
Text('Relation: ${member.relation}',
style: const TextStyle(fontSize: 18)),
const SizedBox(height: 8),
Text('Contact: ${member.contact ?? 'N/A'}',
style: const TextStyle(fontSize: 18)),
const SizedBox(height: 8),
Text('NID: ${member.nid}',
style: const TextStyle(fontSize: 18)),
const SizedBox(height: 8),
Text('Image URL: ${member.faceImg ?? 'N/A'}',
style: const TextStyle(fontSize: 18)),
const SizedBox(height: 8),
Text('Age: ${member.age}',
style: const TextStyle(fontSize: 18)),
const SizedBox(height: 8),
Text('Education: ${member.education ?? 'N/A'}',
style: const TextStyle(fontSize: 18)),
const SizedBox(height: 8),
Text('Income: ${member.income.toString()}',
style: const TextStyle(fontSize: 18)),
const SizedBox(height: 8),
Text('Health: ${member.health ?? 'N/A'}',
style: const TextStyle(fontSize: 18)),
const SizedBox(height: 8),
Text('Created At: ${member.createdAt}',
style: const TextStyle(fontSize: 18)),
const SizedBox(height: 8),
Text('Updated At: ${member.updatedAt ?? 'N/A'}',
style: const TextStyle(fontSize: 18)),
],
),
),
backgroundColor: Colors.black87,
isScrollControlled: true,
);
},
);
},
);
}
}),
I'm getting Error
flutter: type 'Null' is not a subtype of type 'String' in type cast
when i try to view the list of members in my member_controller.dart:
void fetchMembers() async {
isLoading.value = true;
try {
var fetchedMembers = await _api.get('members');
members.value = (fetchedMembers as List)
.map((json) => Member.fromJson(json as Map<String, dynamic>))
.toList();
} catch (e) {
print(e);
Get.snackbar('Controller Error', 'Failed! ${e.toString()}');
} finally {
isLoading.value = false;
}
}
How to solve this Error. as Handling image and file fileds in my Member model between the backend and frontend. is the file the issue?
I've tried to change flutter field type using String? for path or using File both of them gives me issues. so I need experience to title the issue and the right way of handling it and best practice.
Upvotes: 0
Views: 21