【问题标题】:Creating model instance in django在 django 中创建模型实例
【发布时间】:2021-03-09 02:37:32
【问题描述】:

一般任务:有一个显示在表格视图中的事件列表,用户单击事件并被重定向到单个事件页面,该页面显示有关事件的额外信息。

此模板上有一个按钮,该按钮应提供在用户选择的事件列表中记录事件的一些数据的功能。

而且我真的不明白如何将事件数据传递到表单中来创建user_event,也许我选择了错误的方式来创建模型的实例?

模型.py


class Event(models.Model):
    LANGUAGE_CHOICES = [
        ('EN', 'English'), ('IT', 'Italian'), ('FR', 'French'), ('DE', 'German'), ('RU', 'Russian'), ]
    STATUS_CHOICES = [('draft', 'Draft'), ('confirmed', 'Confirmed'), ]
    FORMAT_CHOICES = [('live', 'Live'), ('online', 'Online'), ]
    TOPIC_CHOICES = [('cataract', 'Cataract'),
                     ('vitreo', 'Vitreoretinal'),
                     ('optometry', 'Optometry'),
                     ('multi', 'Multidisciplinary'),
                     ('plastic', 'Plastic and Reconstructive surgery'),
                     ('onco', 'Ocular oncology'),
                     ('glaucoma', 'Glaucoma'),
                     ('pediatrics', 'Pediatrics'), ]
    title = models.CharField(
        max_length=250, verbose_name='Event', db_index=True, default="Event")
    slug = models.SlugField(max_length=250, unique_for_date='publish')
    kol = models.ManyToManyField(
        Kol, verbose_name='Presenter', db_index=True, blank=True)
    body = models.TextField(verbose_name='Description', blank=True)
    publish = models.DateTimeField(default=timezone.now)
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)
    sponsor = models.CharField(
        max_length=150, verbose_name='Sponsored by', default='')
    organizer = models.CharField(
        max_length=150, verbose_name='Organized by', default='')
    topic = models.CharField(
        max_length=100, choices=TOPIC_CHOICES, default='multi', verbose_name='Discipline')
    status = models.CharField(
        max_length=100, choices=STATUS_CHOICES, default='draft')
    event_format = models.CharField(
        max_length=50, choices=FORMAT_CHOICES, default='online', verbose_name='Format', db_index=True)
    main_language = models.CharField(
        max_length=50, choices=LANGUAGE_CHOICES, default='EN', verbose_name='Main language', db_index=True)
    event_url = models.URLField(blank=True)
    event_date_start = models.DateField(
        verbose_name='Start date', db_index=True)
    event_time_start = models.TimeField(default='09:00')
    event_date_finish = models.DateField(
        verbose_name='End date', auto_now=True)
    event_time_finish = models.TimeField(default='18:00')
    is_cme = models.BooleanField(
        default=False, verbose_name='CME credits', db_index=True)

    objects = models.Manager()  # the default manager
    published = PublishedManager()  # published manager
    futured = FutureManager()  # future dates only
    # follow check
    users_follow = models.ManyToManyField(
        settings.AUTH_USER_MODEL, related_name='events_liked', blank=True)

    class Meta:
        ordering = ('event_date_start',)

    def __str__(self):
        return self.title

    def get_kols(self):
        return "\n".join([str(p) for p in self.kol.all()])

    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = slugify(self.title)
        super(Event, self).save(*args, **kwargs)

    @property
    def _month(self):
        return datetime.date(self.event_date_start).month
    event_month = property(_month)

    def get_absolute_url(self):
        return reverse('events:event_detail', args=[self.publish.year,
                                                    self.publish.strftime(
                                                        '%m'),
                                                    self.publish.strftime(
                                                        '%d'),
                                                    self.slug])


class UserEvent(models.Model):
    follower = models.ForeignKey(
        User, related_name='user_events', on_delete=models.CASCADE)
    my_event = models.ForeignKey(
        Event, related_name='selected_event', on_delete=models.CASCADE)
    title = models.CharField(
        max_length=250, verbose_name='Event', db_index=True, default="Event")
    event_url = models.URLField(blank=True)
    event_date_start = models.DateField(
        verbose_name='Start date')
    event_date_finish = models.DateField(
        verbose_name='End date')

    class Meta:
        ordering = ['-event_date_start']

    def save(self, *args, **kwargs):
        created = not self.pk
        super().save(*args, **kwargs)
        if created:
            UserEvent.objects.create(user=self)

    def __str__(self):
        return self.title

forms.py

class UserEventForm(forms.ModelForm):
    class Meta:
        model = UserEvent
        fields = ("title", "event_url",
                  "event_date_start", "event_date_finish")       

带有按钮的detail.html

{% extends 'bbase11.html' %} {% block title %} {{ event.title}} {% endblock %} {% block content %}
<div class="container">
    <h1> {{ event.title }}</h1>
    <p class='event_descr'> {{event.body}}</p>
    <p> Presenting professionals {{event.get_kols}}</p>
    <div>Organized by {{event.organizer}}</div>
    <div>Sponsored by {{event.sponsor}}</div>
    <div> 
    <form action= "{% url "events:add_event" %}" method = "POST" >
    {{form.as_p}}
    {% csrf_token %}
    <input id='event' type='hidden' value = {{event.id}}>
    <button  type="submit" class="btn btn-outline-primary btn-sm m-0 waves-effect">Add to calendar</button></div>
    </form>
</div>
{% endblock %}

views.py

def event_detail(request, year, month, day, event):
    event = get_object_or_404(Event, slug=event,
                              status='confirmed',
                              publish__year=year,
                              publish__month=month,
                              publish__day=day)

    return render(request, 'events/event/detail.html', {'event': event, 'add_event': add_event})

@login_required
def add_event(request):
    if request.method == 'POST':
        form = UserEventForm(request.POST or None)
        if form.is_valid():
            form.save()
            messages.success(request, ("Event has been added"))
            return redirect('event_list')
        else:
            messages.error(request, ("Event has not been added"))
            return redirect('events:event_list')
    else:
        events = Event.futured.all()
        return render(request, 'list.html', {'events': events})

【问题讨论】:

  • 您好,我真的看不出您的问题是什么,因为这个问题对于什么有效,什么无效并不十分准确。从您的代码中,我可以看到当您使用 form.save() doc 时创建了一个 UserEvent。你有什么错误吗?
  • 您只是想用数据预填充表单吗?
  • 是的,这就是想法,我需要从 Event 实例中获取几个字段并创建一个用户特定的 UserEvent 实例。我不需要用户输入任何内容。
  • 然后你可以使用上面的链接到 save() 方法,它告诉你如何预填充表单:f = ArticleForm(request.POST, instance=a)

标签: python django django-models django-forms


【解决方案1】:

使用基于类的视图而不是基于函数的视图,您可以覆盖get_initial 方法,如下所示:

class AddEventCreateView(CreateView):
    model = Event
    form_class = UserEventForm
    template_name = 'your/template.html'

    def get_initial(self):
        initial = super().get_initial()
        # Add your initial values here - for example
        initial['title'] = 'Some value'
        return initial

   def form_valid(self, form):
        self.object = form.save(commit=False)

        # Do something here

        return super().form_valid(form)

    def get_success_url(self):
        return reverse_lazy('your:url-name')

您现在可以根据需要向表单传递任意数量的初始值。详情请见http://ccbv.co.uk/projects/Django/3.0/django.views.generic.edit/CreateView/#get_initial

【讨论】:

    【解决方案2】:

    看起来可能是 detail.html 中的 URL 中带有引号的拼写错误。

    改变这个:

    &lt;form action= "{% url "events:add_event" %}" method = "POST" &gt;

    到这里:

    &lt;form action="{% url 'events:add_event' %}" method="POST"&gt;

    【讨论】:

    • 现在控制台给出一个新的日志 POST /events/add_event HTTP/1.1" 302 0
    猜你喜欢
    • 2013-03-25
    • 1970-01-01
    • 2013-02-11
    • 2021-06-19
    • 2019-01-06
    • 2023-03-23
    • 1970-01-01
    • 1970-01-01
    • 2023-02-08
    相关资源
    最近更新 更多