2014-12-22 2 views
0

Я создаю веб-приложение django, чтобы клиенты могли зарегистрироваться на курсы. На странице «обучение» перечислены все курсы. Пользователи нажимают на курс, чтобы получить более подробную информацию и подать заявку на этот курс. Модель конечно выглядит следующим образом:Текущие значения полей из сеанса в Django

class Course(models.Model): 
    course_text = models.CharField(max_length=200) 
    slug = models.SlugField() 
    leader_text = models.TextField() 
    location = models.CharField(max_length=50) 
    start_date = models.DateField('start date') 
    duration_days = models.CharField (max_length=1) 
    cost = models.DecimalField(max_digits=7, decimal_places=2) 
    available = models.CharField(max_length=2) 
    class Meta: 
     ordering = ['start_date'] 

У меня есть модель приложения «заявитель», который выглядит следующим образом:

class Applicant(models.Model): 
    first_name = models.CharField(max_length=50) 
    last_name = models.CharField(max_length=50) 
    email = models.EmailField(max_length=75) 
    contact_date = models.DateTimeField(auto_now=True) 
    courses = models.ManyToManyField(Course) 

Когда пользователь нажимает на ходу детали этого курса оказываются в view и ModelForm также отображается для процесса приложения. Вид выглядит следующим образом:

def view_course(request, slug): 
    print Course.objects.all() #Just for testing 

    if request.method == "POST": 
     form = ApplicantForm(request.POST) 
     if form.is_valid(): 
      model_instance = form.save(commit=False) 
      model_instance.save() 


      return HttpResponseRedirect('/thanks/') 
    else: 
     form = ApplicantForm() 

    return render(request, 'training/view_course.html', {'course': get_object_or_404(Course, slug=slug), 'form': form}) 

Все из вышеперечисленных работ, и я могу просмотреть список пользователей в моем Джанго администратора, как они применяются. То, что я хотел бы сделать, - собрать конкретную информацию о курсе, к которому они обращаются, и связать это с каждым пользователем. Я надеялся, что отношения ManyToMany в модели «Курс» помогут, но если я включу его в визуализированную форму, он просто даст возможность выбрать любой курс.

Я получаю куда-нибудь с запросами, такими как Course.objects.all(), но мне нужно отфильтровать это на текущих значениях из «Курса» в представлении. Есть ли текущая команда или аналогичные данные, которые хранятся в текущем сеансе?

Я использую Django 1.7 и MySQL в качестве базы данных.

Разъяснения

Я хочу, чтобы отобразить минимум на форме пользователь заполняет, чтобы облегчить процесс подачи заявки. Поэтому требуются только first_name, last_name и email. Я хочу, чтобы эта информация была связана с курсом, который пользователь просматривает в настоящее время, поэтому эти значения автоматически завершаются и не отображаются пользователем.

Что касается многих экземпляров-кандидатов в db, это не так, как работают отношения ManyToMany? На моей странице администратора я хочу, чтобы вы могли нажимать на пользователей и просматривать курсы, на которые они подписались, а также иметь возможность щелкнуть по курсу, чтобы узнать, сколько пользователей было применено. Моя страница администратора еще нигде не приближается, но я хотел иметь возможность сохранить текущую информацию, прежде чем беспокоиться об этом. Вот что администратор выглядит следующим образом:

from django.contrib import admin 
from training.models import Course, Applicant 

class CourseAdmin (admin.ModelAdmin): 
    fieldsets = [ 
     (None,    {'fields': ['course_text', 'location', 'start_date', 'duration_days', 'cost', 'available']}), 
     ('Course details', {'fields': ['leader_text'], 'classes': ['collapse']}), 
     ] 

    list_display = ['course_text', 'location','start_date', 'was_published_recently'] 
    list_filter = ['start_date', 'location'] 
    search_fields = ['course_text'] 



admin.site.register(Course, CourseAdmin) 

class ApplicantAdmin(admin.ModelAdmin): 
    fieldsets = [ 
    (None,    {'fields': ['first_name', 'last_name', 'email',]}), 
    ] 
    list_display = ['first_name', 'last_name','email',] 
    list_filter = ['first_name', 'last_name'] 
    search_fields = ['courses'] 

admin.site.register(Applicant, ApplicantAdmin) 

Решение Сорта

Сначала благодаря spookylukey. Правильно, что у меня было две вещи, и действительно, это может стать проблематичным, если один и тот же пользователь создал несколько объектов-заявителей. Я пытался уйти от идеи auth/auth, поскольку я думаю, что это приводит к большому количеству выпадений. Теперь я вижу, почему это важно.

Этот способ использования spookylukey использования метода Model.ManyToManyField.add() сработал. Код view.py теперь:

def view_course(request, slug): 

courseId = Course.objects.get(slug=slug) 

if request.method == "POST": 
    form = ApplicantForm(request.POST) 
    if form.is_valid(): 

     applicant = form.save(commit=False) 
     applicant.save() 
     form.save_m2m() 
     #The add method working it's magic 
     applicant.courses.add(courseId) 

     return HttpResponseRedirect('/thanks/') 
else: 
    form = ApplicantForm() 
#print request.session['course' : get_object_or_404(Course, slug=slug)] 
return render(request, 'training/view_course.html', {'course': get_object_or_404(Course, slug=slug), 'form': form}) 

дополнительная проблема просмотра отношений в интерфейсе администратора был решен с помощью InlineModelAdmin объектов. Итак, админ.пй выглядит следующим образом:

class SignupsInline(admin.TabularInline): 
    model = Applicant.courses.through 



class CourseAdmin (admin.ModelAdmin): 
    #other styling goes here... 

    inlines = [ 
     SignupsInline, 
    ] 

admin.site.register(Course, CourseAdmin) 

class ApplicantAdmin(admin.ModelAdmin): 
    #other styling goes here... 

    inlines = [ 
     SignupsInline, 
    ] 
admin.site.register(Applicant, ApplicantAdmin) 

Для получения более подробной информации о соответствующем заявителя объекта (в разделе Курс администратора) или объекта курса (в разделе заявитель администратора) я добавил следующую функцию в модели заявителя (и соответствующая модели курса):

def __unicode__(self): 
     return u'%s %s %s' % (self.first_name, self.last_name, self.email) 

Невероятно, но служит своей целью на данный момент.

+0

Я не совсем понимаю, что вы хотите здесь сделать. Есть ли что-нибудь, что вы на самом деле хотите отобразить в форме, или это просто, что вы хотите установить курс, на который они подают заявку вместе с информацией о заявителе? –

+0

И так как ваша форма предназначена для модели-заявителя, как вы управляете тем же пользователем, подписывающимся на несколько курсов? Кажется, что им нужно будет ввести все свои данные для каждого курса, и у вас будет несколько объектов Applicant для них в вашем db. –

+0

Что касается вашего редактирования, то это абсолютно не относится к отношениям «многие ко многим». У вас должен быть * один экземпляр каждого заявителя и * один экземпляр каждого курса, но у каждого заявителя может быть много курсов, и у каждого курса может быть много претендентов. Ваши модели правильно настроены для этого, но ваш вид и форма не являются. –

ответ

3

Похоже, у вас есть две вещи, которые продолжаются:

  • создания Applicant записей, которые я полагаю, вы только хотите, чтобы сделать один раз для каждого пользователя - если пользователь хочет подать заявку на более одного курса, вы не хотите снова запрашивать все свои данные.

  • ассоциированный с Applicant с Course.

Так что я думаю, что вам нужен более сложный технологический процесс - тот, который хранит созданные Applicant данные или идентификатор сессии, и повторно используют по мере необходимости, или запрашивает больше данных.

Независимо от того, сделаете ли вы это, способ исправить ваше мнение - перестать думать о попытке использовать ModelForm для всего. Представление view_course - это не представление, которое позволяет человеку редактировать все о своей записи Applicant - это не позволяет им устанавливать/отменять весь список курсов. Поэтому использование ModelForm для установки courses не подходит. Вместо этого вам необходимо использовать ApplicantAPI that has been created for you by the ORM.

В вашем представлении кода, я полагаю, у вас есть что-то вроде:

course = Course.objects.get(slug=slug) 

Вам нужно будет добавить course заявителю:

applicant = form.save() 
applicant.courses.add(course) 

Объект applicant будет либо извлеченной из возвращаемое значение form.save(), или из сеанса, как я упоминал выше.

+0

Использование 'president.courses.add (курс)' выбрасывает ошибку 'Глобальный заявитель не определен ". Я смущен тем, как добавить информацию о кандидате в базу данных, если я не использую ModelForm. И спасибо за более целостный концептуальный ответ. –

+0

Я попытался уточнить свой код - как я уже сказал, «претендент» должен быть возвращаемым значением 'form.save()'. Это гораздо более четкое имя, чем 'model_instance'. – spookylukey

+0

Извинения. Это работает, но как бы я просмотрел связанные курсы в админке, поскольку «курс» - это неизвестное поле в admin.py и добавление «курсов» в представление администратора показывает список всех доступных курсов, а не только тот, который связан с пользователем , Нужно ли добавлять поле «курс» к моей модели-кандидату? В идеале я также хотел бы видеть кандидатов, связанных с каждым курсом в админ. –

0

При переходе commit=False к ModelForm.save() для модели, которая имеет отношения M2M, вы должны явно сохранить m2ms тоже, ср https://docs.djangoproject.com/en/1.7/topics/forms/modelforms/#the-save-method

IOW, код должен быть:

if request.method == "POST": 
    form = ApplicantForm(request.POST) 
    if form.is_valid(): 
     model_instance = form.save(commit=False) 
     model_instance.save() 
     form.save_m2m() 

Обратите внимание, что если вам нужно будет пропустить commit=False, просто позвоните form.save() и сохраните m2m.

1

Я бы добавил поле M2M к модели курса, где оно будет связано с заявителями. И, по вашему мнению, получите выбранный курс и добавьте кандидата после POST.

course = Course.objects.get(slug=slug) ... course.applicants.add(model_instance)

Смежные вопросы