Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

from django.contrib import admin, messages 

from django.db import transaction 

 

from characters.forms.admin_forms import CharacterChangeForm, CharacterAddForm 

from common.models import Character, Type, CharacterFanfic, Pairing 

 

 

class TypeListFilter(admin.SimpleListFilter): 

# Human-readable title which will be displayed in the 

# right admin sidebar just above the filter options. 

title = 'media type' 

 

# Parameter for the filter that will be used in the URL query. 

parameter_name = 'media' 

 

def lookups(self, request, model_admin): 

""" 

Returns a list of tuples. The first element in each 

tuple is the coded value for the option that will 

appear in the URL query. The second element is the 

human-readable name for the option that will appear 

in the right sidebar. 

""" 

types = Type.objects.values('name') 

 

list_tuples = tuple([(x['name'], x['name']) for x in types]) 

return list_tuples 

 

def queryset(self, request, queryset): 

""" 

Returns the filtered queryset based on the value 

provided in the query string and retrievable via 

`self.value()`. 

""" 

# Compare the requested value (either '80s' or '90s') 

# to decide how to filter the queryset. 

type_name = self.value() 

if type_name: 

# the user filtered by type 

type_obj = Type.objects.filter(name=type_name) 

if type_obj.exists(): 

type_obj = type_obj.first() 

queryset = queryset.filter(fandom__type=type_obj) 

 

return queryset 

 

 

@admin.register(Character) 

class CharacterAdmin(admin.ModelAdmin): 

list_display = ('id', 'name_surname', 

'fandom', 'type') 

list_display_links = ('name_surname',) 

list_filter = (TypeListFilter, 'fandom') 

 

search_fields = ('name_surname', 'fandom__name') 

 

actions = ['merge_characters'] 

 

def type(self, obj): 

return obj.fandom.type 

 

def get_form(self, request, obj=None, **kwargs): 

""" Get the form to show """ 

if obj: 

self.form = CharacterChangeForm 

else: 

self.form = CharacterAddForm 

 

return super(CharacterAdmin, self).get_form(request, obj, **kwargs) 

 

def merge_characters(self, request, queryset): 

""" Merge the characters if they are the same, and they are in the 

same fandom""" 

try: 

with transaction.atomic(): 

if queryset.count() > 2: 

self.message_user(request, 

"You can only join two characters at " 

"the same time.", 

level=messages.ERROR) 

else: 

character_to_keep = queryset.first() 

fandom_one = character_to_keep.fandom 

 

character_to_go = queryset.last() 

fandom_two = character_to_go.fandom 

 

if fandom_one.id != fandom_two.id: 

self.message_user(request, 

"The characters have to be " 

"in the same " 

"fandom.", 

level=messages.ERROR) 

else: 

# only two selected, same fandom, join them 

 

# Character fanfic 

fanfic_characters_to_keep = list( 

CharacterFanfic.objects.filter( 

character=character_to_keep).values_list( 

'fanfic__id', 

flat=True)) 

CharacterFanfic.objects.exclude( 

fanfic__id__in=fanfic_characters_to_keep).filter( 

character=character_to_go).update( 

character=character_to_keep) 

 

# Pairing 

Pairing.objects.filter( 

character_one=character_to_keep, 

character_two=character_to_go).delete() 

Pairing.objects.filter( 

character_two=character_to_keep, 

character_one=character_to_go).delete() 

 

Pairing.objects.filter( 

character_one=character_to_go).update( 

character_one=character_to_keep) 

Pairing.objects.filter( 

character_two=character_to_go).update( 

character_two=character_to_keep) 

 

character_to_go.delete() 

 

# success 

self.message_user(request, 

"The characters have been merged.", 

level=messages.SUCCESS) 

 

except Exception: 

self.message_user(request, 

"There was an unexpected error.", 

level=messages.ERROR) 

 

merge_characters.short_description = "Merge the characters, they are" \ 

" the same"