【问题标题】:Django Admin customizationDjango 管理自定义
【发布时间】:2020-04-01 07:16:17
【问题描述】:

我想在“Model EVENT”的管理面板中添加一个链接,该链接会将我重定向到一个新页面,管理员可以从该页面向注册用户发送电子邮件。 我已经通过在 templates/admin/app/change_form.html 中添加 change_form.html 来尝试它,然后它可以工作,但问题是我想在模型事件中显示的链接也显示在该应用程序的其他模型中,并且当我想要要在应用程序的任何模型中添加对象,它会引发没有反向匹配的错误。 仅帮助我在事件模型的管理面板中添加链接。提前致谢

models.py

from django.db import models
from django.contrib.auth.models import User 
from django.utils.timezone import now
from datetime import date
from django.core.exceptions import ValidationError
from django.shortcuts import reverse
from django.conf import settings

class Venue(models.Model):

    name = models.CharField('Venue Name', max_length=120)
    address = models.CharField(max_length=300)
    zip_code = models.CharField('Zip/Post Code', max_length=12,blank=True, null=True)

    VENUE_STATUS = (
        ('on', 'Online'),
        ('os', 'Onsite'),
        )
    venue_status_label = models.CharField(
        max_length=2,
        choices=VENUE_STATUS,
        default='os',
        help_text='Choose Venue either ONLINE or ONSITE',
        )


    class Meta:
        ordering = ['name']

    def check_status_venue(self):
        if self.venue_status_label == 'on':
            print("Trueeee")
            return True
        else:
            return False

    def __str__(self):
        return self.name


class RegisteredUser(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)

    class Meta:
        ordering = ['user']

    def __str__(self):
        return self.user.username


class Organizer(models.Model):
    name = models.CharField('Organizer Name', max_length=120)
    phone = models.CharField('Contact Phone', max_length=20)
    email_address = models.EmailField('Organizer Email')
    website = models.URLField('Web Address',blank=True, null=True)
    organizer_picture = models.ImageField(help_text="Add image of organizer")

    class Meta:
        ordering = ['name']

    def __str__(self):
        return self.name


class Category(models.Model):
    category_title = models.CharField(max_length=100, help_text="Add category of event")

    class Meta:
        ordering = ['category_title']

    def __str__(self):
        return self.category_title


class Event(models.Model):
    name = models.CharField('Event Name', max_length=120)
    day = models.DateField("Day of Event",default=now)
    start_time = models.TimeField("Starting Time",default=now)
    end_time = models.TimeField("Ending Time",default=now)
    picture = models.ImageField(help_text="Add picture related to event")
    description = models.TextField('Event Description')
    featured = models.BooleanField(default = False)
    categories = models.ManyToManyField(Category)
    cost = models.IntegerField(help_text="Add cost of event in case of free, write 0")
    venue = models.ForeignKey(Venue, on_delete=models.SET_NULL,null=True)
    event_manager = models.ManyToManyField(Organizer,blank =False)
    attendees = models.ManyToManyField(settings.AUTH_USER_MODEL, blank=True)
    slug = models.SlugField()
    EVENT_STATUS = (
        ('o', 'On Time'),
        ('d', 'Delayed'),
        ('c', 'Completed'),
        )

    Event_Show = (
        ('e', 'Enable Event'),
        ('d', 'Disable Event'),
    )

    label = models.CharField(
        max_length=1,
        choices=EVENT_STATUS,
        default='o',
        help_text='Choose Event Status from here',
        )
    Event_Show_Status = models.CharField(max_length=1,choices=Event_Show,default='e',help_text='Either ENABLE and DISABLE your event')

    def get_absolute_url(self):
        return reverse('Events:startup-event-detail', kwargs = {'slug':self.slug})

    class Meta:
        ordering = ['-day']

    def clean(self):
        if self.end_time <= self.start_time:
            raise ValidationError('Ending times must after starting times')

    def __str__(self):
        return self.name

admin.py

@admin.register(Event)
class EventAdmin(admin.ModelAdmin):
    list_display = ('name', 'day', 'venue', 'label')
    list_filter = ('day', 'label', 'featured','Event_Show_Status','venue__venue_status_label',)
    search_fields = ['name','day', 'cost', 'categories__category_title', 'event_manager__name','venue__venue_status_label'] #incomplete searc using venue
    def get_urls(self):
        urls = super().get_urls()
        print("urlsss",urls)

        my_urls = [
            path('<int:event_id>/send_email/', self.send_email, name='send_email'),
        ]

        return my_urls + urls

    def send_email(self, request,event_id ):
        if request.user.is_superuser:
            header = admin.site.site_header
            event_id = event_id
            event = get_object_or_404(Event , pk = event_id)
            list_of_attendess = event.attendees.all()
            form = WebinarMailForm()
            message = ''
            if request.method == 'POST':
                form = WebinarMailForm(request.POST)
                if form.is_valid():
                    subject = form.cleaned_data['Subject']
                    content = form.cleaned_data['Content']
                    event = get_object_or_404(Event , pk = event_id)
                    name = request.user.pk
                    list_of_attendess = event.attendees.all()
                    emails = []
                    for user in list_of_attendess:
                        emails.append(user.email)
                    try:
                        message = "Sent Successfully"
                        send_mail(subject,content,settings.EMAIL_HOST_USER,emails,fail_silently=False)
                    except BadHeaderError:
                        return HttpResponse('Invalid header found.')
            return render(request,'admin/send_email.html', {'form':form,'event_id':event_id,'total_attendees':len(list_of_attendess),'header':header,'message':message} )
        else:
            raise Http404("Only admin can view this page")

templates/admin/sent_email.html

{% extends "admin/app_index.html" %}
{% load i18n %}

{% block title %}{{ title }} | {% trans 'Webinar Email' %}{% endblock %}
{% block branding %}
<h1 id="site-name">{% trans header %}</h1>
{% endblock %}
{% block content %}

<fieldset class="module aligned wide extrapretty">
    <h2>Email Webinar link to Attendees <a href="{% url 'admin:Events_event_changelist' %}" style="color:white">Event List</a>
    <a href="{% url 'admin:Events_event_change' object_id=event_id %}" style="color:white"> Back</a> </h2> 
    </fieldset>
<h3>Total Attendees: {{total_attendees}}</h3>
<form action="{% url 'admin:send_email' event_id=event_id %}" method='post'>  
    {% csrf_token %}
    {% for field in form %}
    <div class="form-group">
        {{field.label_tag}}
        {{field.errors}}
        {{field}}

    </div>
    {% endfor %}
    <input type="submit" value="send mail">
</form>
{{message}}

{% endblock %}

templates/admin/Events(app)/change_form.html

{% extends "admin/change_form.html" %}
{% load i18n admin_urls static admin_modify %}
{% block form_top %}
{% comment %} id of list view original is builtin {{ original.pk }} {% endcomment %}
<fieldset class="module aligned wide extrapretty">
    <h2>Send Webinar attending link to attendees</h2>
    </fieldset>
  <a href="{% url 'admin:send_email' event_id=original.pk %}"> Send Email for Webinar </a>
  <fieldset class="module aligned wide extrapretty">
    <h2>Event Information</h2>
    </fieldset>
{% endblock %}

链接http://127.0.0.1:8000/admin/Events/event/2/send_email/ 将我重定向到send_email 页面并且工作完美,但我只想将它放在我的事件模型的管理面板中。

【问题讨论】:

  • send email 按钮添加为操作不是更好吗?
  • 如何将其添加为操作?

标签: python django django-admin


【解决方案1】:

您可以将send_mail 添加为操作;这样,您需要在ModelAdmin 中进行非常一点 的更改,您还可以选择多个 Events 为他们发送邮件。

这基本上就是你应该如何实现它:

@admin.register(Event)
class EventAdmin(admin.ModelAdmin):
    list_display = ('name', 'day', 'venue', 'label')
    list_filter = ('day', 'label', 'featured','Event_Show_Status','venue__venue_status_label',)
    search_fields = ['name','day', 'cost', 'categories__category_title', 'event_manager__name','venue__venue_status_label'] #incomplete searc using venue

    actions = ['send_mail']

    def send_email(self, request, queryset):
        if request.user.is_superuser:
            header = admin.site.site_header
            event_ids = queryset.values_list('pk', flat=True)
            return HttpResponseRedirect('/send_email/ids=%s' % (
                ','.join(str(pk) for pk in event_ids),
            ))

然后,添加一个urlpath('send_email/', views.send_mail_view) 并移动所有您发送电子邮件的逻辑。

docs 中阅读有关操作的更多信息

【讨论】:

  • 非常感谢这个解决方案,它解决了我的问题。请更正一些操作 = ['send_email'] 和 path('send_email/', views.send_mail_view)
  • 很高兴为您提供帮助。我解决了这些问题,谢谢(顺便说一句,您可以建议对答案进行编辑)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-16
  • 2018-09-07
  • 2011-10-08
  • 2014-06-23
  • 2011-05-03
  • 2018-06-27
相关资源
最近更新 更多